acoustid

Chromaprint 1.4 released

A new version of Chromaprint has been released. This is a fairly big release I originally intended to call 2.0, but one key feature I was planning to include is not yet finished, so I decided to go with 1.4 instead.

Chromaprint 1.3.2 released

A new version of Chromaprint has been released. This is a very small bug fix release fixing fpcalc crash on a corrupt file.

Chromaprint 1.3 released

A new version of Chromaprint has been released. This is another small release, there are no changes to the core functionality.

Five years of AcoustID

It’s hard to tell the exact date when the AcoustID project started, but if we go by the first entry in the database, it was October 8, 2010. That means project turned five this week! I thought it’s a good opportunity to gather some statistics from those five years.

AcoustID Demo API Key Changed

It seems that some people have been using the AcoustID demo API key from the documentation page for more than just testing, so it’s time to change it.

Chromaprint 1.2 released

A new version of Chromaprint has been released. This release doesn’t add any new features to the library, but there are some source code changes for better compatibility when building the library in non-standard situations.

Chromaprint 1.1 released

A new version of Chromaprint has been released. There are a few bug fixes, fixed compilation error on OS X 10.9 and added support for compilation with libav (FFmpeg is still the preferred library to use with Chromaprint).

Chromaprint 1.0 released

A new version of Chromaprint has been released. There are no changes to the library, just the fpcalc utility. The main changes are support for the latest version of the FFmpeg.

AcoustID: Invalid API key?

Short version: I’m sorry, but today I had to block some applications from the AcoustID web service. If you were using AcoustID and now get an “invalid API key” error, please contact me.

AcoustID code moved to Bitbucket

I was not very happy when GitHub announced that it discontinues project downloads. I was using GitHub to host compiled packages for Chromaprint and the AcoustID fingerprinter, as well as release tarballs for all AcoustID projects, so I had to start looking for alternatives.

AcoustID: Faster fingerprint importing

Asynchronous importing of user submissions was always a big part of the AcoustID architecture. It makes things much easier to handle on the server side, allows database maintenance without turning the service to read-only mode (just delays the imports) and has many other benefits.

Chromaprint 0.7 released

A new version of Chromaprint has been released. The main change is compatibility with the latest FFmpeg API. There is also a modified fingerprint algorithm, that ignores leading silence up to a specific threshold, but this has no impact on Acoustid users.

Acoustid fingerprinter 0.6 released

A new version of the Acoustid fingerprinter has been released. The main change is compatibility with the latest FFmpeg API and fix for a crash when compiled with FFTW3.

New AcoustID server release

I’ve just updated the AcoustID servers with the latest version of the code. There is a couple of changes on both the website and the API.

Acoustid fingerprinter 0.5 released

A new version of the Acoustid fingerprinter has been released. The version adds support for Unicode file names on Windows, reading 24-bit audio file formats and can parse MBID tags from MP3 files written by foo_musicbrainz.

Chromaprint 0.6 released

A new version of Chromaprint has been released. As with the previous version, the core library hasn’t changed much. The fpcalc utility now supports 24-bit sample formats and by default calculates fingerprints using the first 2 minutes of audio. The Python bindings previously included in Chromaprint have been moved to a separate library, pyacoustid.

AcoustID server release

I guess it’s time for AcoustID to have release notes when something gets released, so here is my first AcoustID server release blog post.

Chromaprint 0.5 released

A new version of Chromaprint has been released. The code library hasn’t been changed, but there are some bug fixes in the fpcalc utility and the Python bindings.

Acoustid database rebuilding

I’ve released a new version of the Acoustid server today. This release changes the way fingerprints are matched, so it required the database to be rebuilt, which means all previous “track IDs” will be lost. I’m expecting it will take at least a week before the database is back at the full size. This is probably the last rebuild and the IDs will stay stable from now on, but in case I discover some serious problems it might be necessary to do it one more time.

Acoustid fingerprinter 0.4 released

I’ve just released a new version of the Acoustid fingerprinter. I’ve sneakily released 0.3 some time ago, but it was available only on Linux. The only change was support for reading of the PUID tags. This release brings that functionality also to Windows and OS X, plus a few bug fixes.

Acoustid submissions without MBIDs

I’ve released a new version of the Acoustid server that doesn’t require submissions to include MusicBrainz recording IDs. Applications can send textual metadata (track, artist, album, album artist, year, track number, disc number) instead and the server will try to match the tags to MusicBrainz by itself. The matching is actually not yet implemented, but the server is able to collect the data. The format of the metadata is described in the web service documentation.

Chromaprint 0.4 released

A new version of Chromaprint has been released. The main change is addition of an example application that uses the public C API and FFmpeg to allow externals programs to use Chromaprint without linking to the library. Other than this, there were some build system changes and added support for the latest development version of FFmpeg.

New Acoustid web service

Some time ago I realized that having the server code in Java keeps me away from working more on it. The original reason for writing it in Java was that I expected it would do harder work, but I really don’t need a “fast” language for simply running SQL queries. Additionally, since developing simple websites in Java turned out to be a pain, I used PHP to do the Acoustid website. I have no problem with PHP, but later I wanted to start integrating the website with the rest of the fingerprint database and it felt like a waste of my time to not share code, which is not easy if some parts are in Java, some in PHP. So, today I’ve released a new version of the server which is written completely in Python.

Chromaprint 0.3 released

A new version of Chromaprint has been released. There aren’t many changes, mostly just compatibility improvements for Windows and Mac OS X, plus simple ctypes-based Python bindings.

Acoustid moved one more time

Last week, with the help from Zvooq, the Acoustid service was moved one more time, this time to a much more powerful server. This move made it possible to import all submissions from the backlog, so the database now contains fingerprints for over 5M unique tracks. Unfortunately, only around 2.4M of them are matched to the MusicBrainz database, but I’m hoping that the ratio will improve soon.

Chromaprint 0.2

I’m not good at releasing code, as this should have been done a long time ago, but I’ve finally released the version 0.2 of Chromaprint. The main changes are new functions in the public API for working with raw fingerprints and safe releasing of memory allocated internally in Chromaprint.

How does Chromaprint work?

I’ve been meaning to write this post for a long time, but never really finished it. I hope it will help people understand how does the Chromaprint algorithm work, where do the individual ideas come from and what do the fingerprints really represent. It’s not meant to be a detailed description, just the basics to get the general idea.

Acoustid database dump available

I’ve finally written a script to take a consistent dump of the Acoustid database in the PostgreSQL tab-separated format used by the COPY command. I do not have any tools for importing it into PostgreSQL, so it has to be done manually by running SQL commands, but if anybody is interested in playing with the database, you can download it here (2.7G after compression using bzip2, 6.4G uncompressed). The data is licensed under a Creative Commons BY-SA 3.0 License. I’ll add a cron job to export the database at the beginning of every month.

Acoustid submission API extended to accept PUIDs

As strange as it might sound, the Acoustid submission API can now also accept PUIDs instead of MBIDs. I had the idea of using PUIDs to help bootstrap the Acoustid database for a long time, but I avoided implementing it, because I was afraid of bringing all the PUID↔MBID matching errors to the database. The topic came up yesterday and I realized that with having the audio fingerprints, MBIDs and MusicBrainz metadata in the same database, I can pretty easily remove any suspicious matches. So I’ve made two changes to the submission API that should make importing of untagged audio files easier:

Chromaprint plug-in for GStreamer

It’s been a long time since I learned some new framework (or even wrote some real code), so I decided to write a GStreamer plug-in that will wrap libchromaprint and make it very easy to generate Chromaprint fingerprints in GStreamer applications. This was inspired by a similar plug-in that Milosz Derezynski wrote for MusicDNS/libofa (the plug-in is now integrated in the official GStreamer distribution). Using the code from gst-ofa and gst-template, it turned out to be pretty easy. After a couple of hours, I was able to run commands like this and get valid fingerprints:

Acoustid moved to a new server

Since I announced the Acoustid project, I got over 1.1 million fingerprint submissions (mostly from MusicBrainz editors), covering about 580 thousand unique MusicBrainz track IDs. In the background I was running a process that imported the raw submissions and merged similar tracks. All this was done on a virtual machine with 1GB of RAM. It wasn’t very fast, but I was surprised it was even able to handle such amount of data. At some point I also enabled the lookup service, but I didn’t want to announce it, because it took too long to do fingerprint searches on the server.

Binary fingerprint compression

While working on the Acoustid web service, I had a hard time deciding how to send fingerprints to the server. The fingerprints are vectors of fairly large 32-bit numbers. Sending the numbers in binary (which would be ideal) is not easy, because almost all web standards expect textual data, if not plain ASCII. The usual trick is to base64-encode binary data, but that increases the size by 33 %, which wasn’t acceptable for me. So I came up with the idea to compress the data using a special-purpose algorithm and then base64-encode the compressed data, and ideally also compress the base64-encoded data using GZip. The double-compression might seem weird, but it allows me to use only standard web tools and the resulting size is still smaller than using binary encoding.

Acoustid Fingerprinter 0.1 released

After posting about the beta version of Acoustid Fingerprinter, some people successfully used it to submit fingerprints and I also started using it as the main tool for submitting fingerprints, so I think it’s time for a proper release. More details on the wiki:

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

Introducing Chromaprint

After several months of reading research papers, learning and weekend coding, I’m very happy to make the half-finished code of my audio fingerprinting library public. :) I’m doing this mostly for selfish reasons, because it will force me to stop thinking in “hacker mode” and hopefully properly finish it, and I also hope to get some help and feedback from other people. There is nothing for regular users yet though, just for developers or people not afraid of the command line.

Back to Top ↑

release

Chromaprint 1.4 released

A new version of Chromaprint has been released. This is a fairly big release I originally intended to call 2.0, but one key feature I was planning to include is not yet finished, so I decided to go with 1.4 instead.

mbdata 2016.07.17 released

I have released a new version of mbdata. It’s a small Python package for working with the MusicBrainz database using SQLAlchemy.

Chromaprint 1.3.2 released

A new version of Chromaprint has been released. This is a very small bug fix release fixing fpcalc crash on a corrupt file.

Chromaprint 1.3 released

A new version of Chromaprint has been released. This is another small release, there are no changes to the core functionality.

Chromaprint 1.2 released

A new version of Chromaprint has been released. This release doesn’t add any new features to the library, but there are some source code changes for better compatibility when building the library in non-standard situations.

Chromaprint 1.1 released

A new version of Chromaprint has been released. There are a few bug fixes, fixed compilation error on OS X 10.9 and added support for compilation with libav (FFmpeg is still the preferred library to use with Chromaprint).

Chromaprint 1.0 released

A new version of Chromaprint has been released. There are no changes to the library, just the fpcalc utility. The main changes are support for the latest version of the FFmpeg.

AcoustID: Faster fingerprint importing

Asynchronous importing of user submissions was always a big part of the AcoustID architecture. It makes things much easier to handle on the server side, allows database maintenance without turning the service to read-only mode (just delays the imports) and has many other benefits.

TagLib 1.8 released

I’m sorry this took longer than expected, but I’ve just released the final version of TagLib 1.8. There are a few changes compared to the beta version, see the change log below.

Chromaprint 0.7 released

A new version of Chromaprint has been released. The main change is compatibility with the latest FFmpeg API. There is also a modified fingerprint algorithm, that ignores leading silence up to a specific threshold, but this has no impact on Acoustid users.

Acoustid fingerprinter 0.6 released

A new version of the Acoustid fingerprinter has been released. The main change is compatibility with the latest FFmpeg API and fix for a crash when compiled with FFTW3.

New AcoustID server release

I’ve just updated the AcoustID servers with the latest version of the code. There is a couple of changes on both the website and the API.

Acoustid fingerprinter 0.5 released

A new version of the Acoustid fingerprinter has been released. The version adds support for Unicode file names on Windows, reading 24-bit audio file formats and can parse MBID tags from MP3 files written by foo_musicbrainz.

Chromaprint 0.6 released

A new version of Chromaprint has been released. As with the previous version, the core library hasn’t changed much. The fpcalc utility now supports 24-bit sample formats and by default calculates fingerprints using the first 2 minutes of audio. The Python bindings previously included in Chromaprint have been moved to a separate library, pyacoustid.

AcoustID server release

I guess it’s time for AcoustID to have release notes when something gets released, so here is my first AcoustID server release blog post.

Chromaprint 0.5 released

A new version of Chromaprint has been released. The code library hasn’t been changed, but there are some bug fixes in the fpcalc utility and the Python bindings.

Acoustid fingerprinter 0.4 released

I’ve just released a new version of the Acoustid fingerprinter. I’ve sneakily released 0.3 some time ago, but it was available only on Linux. The only change was support for reading of the PUID tags. This release brings that functionality also to Windows and OS X, plus a few bug fixes.

Acoustid submissions without MBIDs

I’ve released a new version of the Acoustid server that doesn’t require submissions to include MusicBrainz recording IDs. Applications can send textual metadata (track, artist, album, album artist, year, track number, disc number) instead and the server will try to match the tags to MusicBrainz by itself. The matching is actually not yet implemented, but the server is able to collect the data. The format of the metadata is described in the web service documentation.

Chromaprint 0.4 released

A new version of Chromaprint has been released. The main change is addition of an example application that uses the public C API and FFmpeg to allow externals programs to use Chromaprint without linking to the library. Other than this, there were some build system changes and added support for the latest development version of FFmpeg.

Chromaprint 0.3 released

A new version of Chromaprint has been released. There aren’t many changes, mostly just compatibility improvements for Windows and Mac OS X, plus simple ctypes-based Python bindings.

TagLib 1.7 released

TagLib 1.7 has been released. This release adds support for Monkey’s Audio files and cover art reading/writing for WMA and FLAC files. There is also a number of bug fixes, more details in the changelog. There are two important changes associated with this release:

Picard 0.13 released

MusicBrainz Picard wasn’t under active development for a long time. In fact, the last release was in November 2009. Even due to the situation, some bug fixes accumulated in the source control repository over the time, so the primary goal of this release is to publish these bug fixes. There were also a few larger patches, such us the sorting support by Aaron Lambers, but these are not included in this release. I’m hoping that patches like that will get committed now that 0.13 is released and a new release will follow in less than a year from now. :)

TagLib 1.7 RC1 released

Even though I wasn’t planning to make a 1.7 release by the time 1.6.3 was released, moving forward with the 1.x series seems to be the easiest way to go. There are many new features in this version. The biggest ones are full support for Monkey’s Audio files and cover art support for WMA and FLAC files. There are also a number of bug fixes. The reason why I decided to go with a RC is that some code had to be rewritten in order to add the new features, so I’d like more people to test it before there is a final release. Also, if I’ve forgotten about somebody’s patch that should be included in the final release, please let me know.

Chromaprint 0.2

I’m not good at releasing code, as this should have been done a long time ago, but I’ve finally released the version 0.2 of Chromaprint. The main changes are new functions in the public API for working with raw fingerprints and safe releasing of memory allocated internally in Chromaprint.

Acoustid Fingerprinter 0.1 released

After posting about the beta version of Acoustid Fingerprinter, some people successfully used it to submit fingerprints and I also started using it as the main tool for submitting fingerprints, so I think it’s time for a proper release. More details on the wiki:

TagLib 1.6.3

TagLib 1.6.3 was released this Monday, but somehow I forgot to post an update here. There isn’t many changes, the main reason for the release were configuration issues with 1.6.2. The 1.6.3 tarball can be downloaded here or here.

Database Modeller 0.3

Database Modeller 0.3 has been released. There isn’t as many changes as I wanted, but the main changes were unreleased for almost half a year. You can download the source code and Windows installer on the project page.

TagLib 1.6.1

TagLib 1.6.1 has been released. It’s a minor bug-fix release. Main changes are content-based detection of .oga files, saving Vorbis Comments to Ogg FLAC files and support for cover art in MP4 files. Tarball is available here for now, later also on Scott’s page, and updated API docs are here.

Back to Top ↑

chromaprint

Chromaprint 1.4 released

A new version of Chromaprint has been released. This is a fairly big release I originally intended to call 2.0, but one key feature I was planning to include is not yet finished, so I decided to go with 1.4 instead.

Chromaprint 1.3.2 released

A new version of Chromaprint has been released. This is a very small bug fix release fixing fpcalc crash on a corrupt file.

Chromaprint 1.3 released

A new version of Chromaprint has been released. This is another small release, there are no changes to the core functionality.

Five years of AcoustID

It’s hard to tell the exact date when the AcoustID project started, but if we go by the first entry in the database, it was October 8, 2010. That means project turned five this week! I thought it’s a good opportunity to gather some statistics from those five years.

Chromaprint 1.2 released

A new version of Chromaprint has been released. This release doesn’t add any new features to the library, but there are some source code changes for better compatibility when building the library in non-standard situations.

Chromaprint 1.1 released

A new version of Chromaprint has been released. There are a few bug fixes, fixed compilation error on OS X 10.9 and added support for compilation with libav (FFmpeg is still the preferred library to use with Chromaprint).

Chromaprint 1.0 released

A new version of Chromaprint has been released. There are no changes to the library, just the fpcalc utility. The main changes are support for the latest version of the FFmpeg.

Chromaprint 0.7 released

A new version of Chromaprint has been released. The main change is compatibility with the latest FFmpeg API. There is also a modified fingerprint algorithm, that ignores leading silence up to a specific threshold, but this has no impact on Acoustid users.

Chromaprint 0.6 released

A new version of Chromaprint has been released. As with the previous version, the core library hasn’t changed much. The fpcalc utility now supports 24-bit sample formats and by default calculates fingerprints using the first 2 minutes of audio. The Python bindings previously included in Chromaprint have been moved to a separate library, pyacoustid.

Chromaprint 0.5 released

A new version of Chromaprint has been released. The code library hasn’t been changed, but there are some bug fixes in the fpcalc utility and the Python bindings.

Chromaprint 0.4 released

A new version of Chromaprint has been released. The main change is addition of an example application that uses the public C API and FFmpeg to allow externals programs to use Chromaprint without linking to the library. Other than this, there were some build system changes and added support for the latest development version of FFmpeg.

Chromaprint 0.3 released

A new version of Chromaprint has been released. There aren’t many changes, mostly just compatibility improvements for Windows and Mac OS X, plus simple ctypes-based Python bindings.

Chromaprint 0.2

I’m not good at releasing code, as this should have been done a long time ago, but I’ve finally released the version 0.2 of Chromaprint. The main changes are new functions in the public API for working with raw fingerprints and safe releasing of memory allocated internally in Chromaprint.

How does Chromaprint work?

I’ve been meaning to write this post for a long time, but never really finished it. I hope it will help people understand how does the Chromaprint algorithm work, where do the individual ideas come from and what do the fingerprints really represent. It’s not meant to be a detailed description, just the basics to get the general idea.

Acoustid submission API extended to accept PUIDs

As strange as it might sound, the Acoustid submission API can now also accept PUIDs instead of MBIDs. I had the idea of using PUIDs to help bootstrap the Acoustid database for a long time, but I avoided implementing it, because I was afraid of bringing all the PUID↔MBID matching errors to the database. The topic came up yesterday and I realized that with having the audio fingerprints, MBIDs and MusicBrainz metadata in the same database, I can pretty easily remove any suspicious matches. So I’ve made two changes to the submission API that should make importing of untagged audio files easier:

Chromaprint plug-in for GStreamer

It’s been a long time since I learned some new framework (or even wrote some real code), so I decided to write a GStreamer plug-in that will wrap libchromaprint and make it very easy to generate Chromaprint fingerprints in GStreamer applications. This was inspired by a similar plug-in that Milosz Derezynski wrote for MusicDNS/libofa (the plug-in is now integrated in the official GStreamer distribution). Using the code from gst-ofa and gst-template, it turned out to be pretty easy. After a couple of hours, I was able to run commands like this and get valid fingerprints:

Acoustid moved to a new server

Since I announced the Acoustid project, I got over 1.1 million fingerprint submissions (mostly from MusicBrainz editors), covering about 580 thousand unique MusicBrainz track IDs. In the background I was running a process that imported the raw submissions and merged similar tracks. All this was done on a virtual machine with 1GB of RAM. It wasn’t very fast, but I was surprised it was even able to handle such amount of data. At some point I also enabled the lookup service, but I didn’t want to announce it, because it took too long to do fingerprint searches on the server.

Binary fingerprint compression

While working on the Acoustid web service, I had a hard time deciding how to send fingerprints to the server. The fingerprints are vectors of fairly large 32-bit numbers. Sending the numbers in binary (which would be ideal) is not easy, because almost all web standards expect textual data, if not plain ASCII. The usual trick is to base64-encode binary data, but that increases the size by 33 %, which wasn’t acceptable for me. So I came up with the idea to compress the data using a special-purpose algorithm and then base64-encode the compressed data, and ideally also compress the base64-encoded data using GZip. The double-compression might seem weird, but it allows me to use only standard web tools and the resulting size is still smaller than using binary encoding.

Acoustid Fingerprinter 0.1 released

After posting about the beta version of Acoustid Fingerprinter, some people successfully used it to submit fingerprints and I also started using it as the main tool for submitting fingerprints, so I think it’s time for a proper release. More details on the wiki:

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

Introducing Chromaprint

After several months of reading research papers, learning and weekend coding, I’m very happy to make the half-finished code of my audio fingerprinting library public. :) I’m doing this mostly for selfish reasons, because it will force me to stop thinking in “hacker mode” and hopefully properly finish it, and I also hope to get some help and feedback from other people. There is nothing for regular users yet though, just for developers or people not afraid of the command line.

Back to Top ↑

musicbrainz

mbdata 2016.07.17 released

I have released a new version of mbdata. It’s a small Python package for working with the MusicBrainz database using SQLAlchemy.

Daily Picard builds for Windows

Building the Windows installer of MusicBrainz Picard has always been problematic. I never had the process automated, it always involved a lot of manual steps which I could never remember. And because Picard releases do not happen very often, it was not very easy for people to test with the latest version on Windows (which usually included a number of fixes.

Alternative MusicBrainz search server

If you are working with a local MusicBrainz database and want to search in it, there aren’t that many choices. You can use the internal PostgreSQL full-text search or you can use the official MusicBrainz search server.

Easier MusicBrainz NGS database setup

Some time ago I wrote a couple of tools that help me set up and update a mirror of the MusicBrainz database on the Acoustid server. It turned out to be work really well. Recently I’ve seen a few people struggling with setting up the NGS database using the original server codebase. The official route assumes you are going to run a MB server instance, which makes things a little bit more complicated than it has to be. You have to install a number Perl modules, you have to compile the MusicBrainz-specific PostgreSQL extensions, even though you most likely don’t need them, you are forced to setup a musicbrainz_db_raw database that you are definitely not going to use, because there is no data in it, etc.

Picard 0.13 released

MusicBrainz Picard wasn’t under active development for a long time. In fact, the last release was in November 2009. Even due to the situation, some bug fixes accumulated in the source control repository over the time, so the primary goal of this release is to publish these bug fixes. There were also a few larger patches, such us the sorting support by Aaron Lambers, but these are not included in this release. I’m hoping that patches like that will get committed now that 0.13 is released and a new release will follow in less than a year from now. :)

MusicBrainz database replication

I wanted to work on the Acoustid lookup web service and for this I needed to setup a MusicBrainz replicated database slave. Normally I’d use the Perl code from mb_server, but I didn’t want to mess up the setup I have on the machine hosting acoustid.org with CPAN packages. I had a plan to write a non-Perl version of the replicated code earlier, but only yesterday I really needed it. It turned out to be easier than I expected, so I already have a working version that I use to update my local MB database. Get it from GitHub, if you would like to give it a try.

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

Introducing Chromaprint

After several months of reading research papers, learning and weekend coding, I’m very happy to make the half-finished code of my audio fingerprinting library public. :) I’m doing this mostly for selfish reasons, because it will force me to stop thinking in “hacker mode” and hopefully properly finish it, and I also hope to get some help and feedback from other people. There is nothing for regular users yet though, just for developers or people not afraid of the command line.

Submit tags from Quod Libet to MusicBrainz

I wanted to write something like this for a long time, but for some reason never did it. MusicBrainz has support for folksonomy tagging since 2007, but the coverage of track tags is still not very good. I try to keep some tags in the “genre” tag in audio files, but even with one-time import tool, I’m sure I’d not remember to run this on new files. So the idea here is to submit these tags to MusicBrainz as I listen to the files in my music player (Quod Libet). It’s inspired by a Quod Libet plugin called LastFMTagger, which does something similar, but for Last.fm. I had some free time today, so I wrote a plugin that does one-way synchronization of tags from Quod Libet to MusicBrainz. You can install the plugin using the following commands:

“Punchcard” graphs for Bazaar

GitHub has a nice feature called “Punchcard”. It’s a graph that represents numbers of commits by day and hour (example). You can easily see wherether a project was hacked over weekends or nights, if it’s done by full-time employees, etc. There are two problems though:

UUID generator in PL/pgSQL

While writing an SQL script to upgrade the MusicBrainz database for the last release, I needed a way to generate new UUIDs from SQL. PostgreSQL has a native UUID data type and a contrib module for generating UUIDs since version 8.3, but this wouldn’t help me, because I needed it to work with at least version 8.1. I had this idea to write PL/pgSQL functions to generate UUIDs, so I skimmer over the RFC 4122 that documents them and found out that it isn’t actually that hard.

Back to Top ↑

python

mbdata 2016.07.17 released

I have released a new version of mbdata. It’s a small Python package for working with the MusicBrainz database using SQLAlchemy.

Phoenix database adapter for Python

This is a small project I have been working on for a few weeks now. Mainly to get familiar with the Phoenix database, but also to just try something different from what I do at work or my existing open source projects.

Closure Templates (Soy) for Python

For the past two weeks I’ve been adding a Python backend to Google’s Closure Templates. The work is now almost finished, so I’m happy to release a preview version of the Soy-to-Python compiler with a runtime Python library (closure-templates-for-python) and a Flask extension (Flask-Soy), to make it possible to work with Soy templates from Python.

Twisted Trial and Jenkins

It’s not completely obvious how to configure a Twisted-based job that uses Trial for running tests in Jenkins, so hopefully this post will save somebody a little time in the future.

Extending the SQLAlchemy SQL expression language

The SQL expression language from SQLAlchemy is already very flexible and allows you to build almost any standard SQL query, but sometimes you just need to use a SQL extension that isn’t supported by SQLAlchemy.

New Acoustid web service

Some time ago I realized that having the server code in Java keeps me away from working more on it. The original reason for writing it in Java was that I expected it would do harder work, but I really don’t need a “fast” language for simply running SQL queries. Additionally, since developing simple websites in Java turned out to be a pain, I used PHP to do the Acoustid website. I have no problem with PHP, but later I wanted to start integrating the website with the rest of the fingerprint database and it felt like a waste of my time to not share code, which is not easy if some parts are in Java, some in PHP. So, today I’ve released a new version of the server which is written completely in Python.

Acoustid submission API extended to accept PUIDs

As strange as it might sound, the Acoustid submission API can now also accept PUIDs instead of MBIDs. I had the idea of using PUIDs to help bootstrap the Acoustid database for a long time, but I avoided implementing it, because I was afraid of bringing all the PUID↔MBID matching errors to the database. The topic came up yesterday and I realized that with having the audio fingerprints, MBIDs and MusicBrainz metadata in the same database, I can pretty easily remove any suspicious matches. So I’ve made two changes to the submission API that should make importing of untagged audio files easier:

Chromaprint plug-in for GStreamer

It’s been a long time since I learned some new framework (or even wrote some real code), so I decided to write a GStreamer plug-in that will wrap libchromaprint and make it very easy to generate Chromaprint fingerprints in GStreamer applications. This was inspired by a similar plug-in that Milosz Derezynski wrote for MusicDNS/libofa (the plug-in is now integrated in the official GStreamer distribution). Using the code from gst-ofa and gst-template, it turned out to be pretty easy. After a couple of hours, I was able to run commands like this and get valid fingerprints:

MusicBrainz database replication

I wanted to work on the Acoustid lookup web service and for this I needed to setup a MusicBrainz replicated database slave. Normally I’d use the Perl code from mb_server, but I didn’t want to mess up the setup I have on the machine hosting acoustid.org with CPAN packages. I had a plan to write a non-Perl version of the replicated code earlier, but only yesterday I really needed it. It turned out to be easier than I expected, so I already have a working version that I use to update my local MB database. Get it from GitHub, if you would like to give it a try.

“MySQL server has gone away”

I have written a few Twisted scripts at work that parse incoming data from a socket and save it in a MySQL database, using the MySQLdb package. It’s a well-known fact that the MySQL server will close connections that are inactive for some time and yet I forgot to handle it in last script I wrote. Previously I solved the problem by remembering the last time I used the connection and forcing a reconnect based on this value or the recycle option in SQLAlchemy’s connection pool when I needed a connection pool (which does basically the same as the former). But when I found the problem in the latest script today, I thought I should finally solved it properly, so I started Googling…

Back to Top ↑

taglib

TagLib 1.8 released

I’m sorry this took longer than expected, but I’ve just released the final version of TagLib 1.8. There are a few changes compared to the beta version, see the change log below.

TagLib 1.7 released

TagLib 1.7 has been released. This release adds support for Monkey’s Audio files and cover art reading/writing for WMA and FLAC files. There is also a number of bug fixes, more details in the changelog. There are two important changes associated with this release:

TagLib 1.7 RC1 released

Even though I wasn’t planning to make a 1.7 release by the time 1.6.3 was released, moving forward with the 1.x series seems to be the easiest way to go. There are many new features in this version. The biggest ones are full support for Monkey’s Audio files and cover art support for WMA and FLAC files. There are also a number of bug fixes. The reason why I decided to go with a RC is that some code had to be rewritten in order to add the new features, so I’d like more people to test it before there is a final release. Also, if I’ve forgotten about somebody’s patch that should be included in the final release, please let me know.

TagLib 1.6.3

TagLib 1.6.3 was released this Monday, but somehow I forgot to post an update here. There isn’t many changes, the main reason for the release were configuration issues with 1.6.2. The 1.6.3 tarball can be downloaded here or here.

TagLib 1.6.1

TagLib 1.6.1 has been released. It’s a minor bug-fix release. Main changes are content-based detection of .oga files, saving Vorbis Comments to Ogg FLAC files and support for cover art in MP4 files. Tarball is available here for now, later also on Scott’s page, and updated API docs are here.

Back to Top ↑

snippet

Cross-compiling with CMake and Autotools

[The last time]/2010/07/introducing-chromaprint/) I needed to build a Windows binary, I found it easier to cross-compile it from Linux than to setup a development environment on a freshly installed Windows machine. The problem is that even though it’s not hard, you need to remember some obscure options. Today I needed to build a new version of ISRCsubmit and I had to search for the recipe again. So, let’s document it somewhere I can find it in the future…

Tomboy’s “Start Here” note

I use Dropbox to synchronize my Tomboy notes. This works very well, but there is a problem when setting it up on a new computer. Tomboy has a special “Start Here” note, which is used mainly for organizing other notes. When I tell it to synchronize notes from the Dropbox directory and overwrite the existing default notes, it will do so, but it doesn’t change it’s “Start Here” note pointer. As as result, Tomboy is not aware that my new Start Here note is the one it should use. As far as I know, there is no way fix this using Tomboy itself. It can be done only using GConf. Here is an example how to do it from the command line:

Resizing a LVM swap volume

Another post mainly for myself, just so I know where to find the information quickly the next time I need it. If you have swap on a LVM volume, these commands can be used to resize it (in this case, increase by 100MB):

Back to Top ↑

fingerprinting

How does Chromaprint work?

I’ve been meaning to write this post for a long time, but never really finished it. I hope it will help people understand how does the Chromaprint algorithm work, where do the individual ideas come from and what do the fingerprints really represent. It’s not meant to be a detailed description, just the basics to get the general idea.

Acoustid moved to a new server

Since I announced the Acoustid project, I got over 1.1 million fingerprint submissions (mostly from MusicBrainz editors), covering about 580 thousand unique MusicBrainz track IDs. In the background I was running a process that imported the raw submissions and merged similar tracks. All this was done on a virtual machine with 1GB of RAM. It wasn’t very fast, but I was surprised it was even able to handle such amount of data. At some point I also enabled the lookup service, but I didn’t want to announce it, because it took too long to do fingerprint searches on the server.

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

Introducing Chromaprint

After several months of reading research papers, learning and weekend coding, I’m very happy to make the half-finished code of my audio fingerprinting library public. :) I’m doing this mostly for selfish reasons, because it will force me to stop thinking in “hacker mode” and hopefully properly finish it, and I also hope to get some help and feedback from other people. There is nothing for regular users yet though, just for developers or people not afraid of the command line.

Back to Top ↑

fingerprinter

Acoustid fingerprinter 0.6 released

A new version of the Acoustid fingerprinter has been released. The main change is compatibility with the latest FFmpeg API and fix for a crash when compiled with FFTW3.

Acoustid fingerprinter 0.5 released

A new version of the Acoustid fingerprinter has been released. The version adds support for Unicode file names on Windows, reading 24-bit audio file formats and can parse MBID tags from MP3 files written by foo_musicbrainz.

Acoustid fingerprinter 0.4 released

I’ve just released a new version of the Acoustid fingerprinter. I’ve sneakily released 0.3 some time ago, but it was available only on Linux. The only change was support for reading of the PUID tags. This release brings that functionality also to Windows and OS X, plus a few bug fixes.

Acoustid submissions without MBIDs

I’ve released a new version of the Acoustid server that doesn’t require submissions to include MusicBrainz recording IDs. Applications can send textual metadata (track, artist, album, album artist, year, track number, disc number) instead and the server will try to match the tags to MusicBrainz by itself. The matching is actually not yet implemented, but the server is able to collect the data. The format of the metadata is described in the web service documentation.

Acoustid Fingerprinter 0.1 released

After posting about the beta version of Acoustid Fingerprinter, some people successfully used it to submit fingerprints and I also started using it as the main tool for submitting fingerprints, so I think it’s time for a proper release. More details on the wiki:

Back to Top ↑

database

Extending the SQLAlchemy SQL expression language

The SQL expression language from SQLAlchemy is already very flexible and allows you to build almost any standard SQL query, but sometimes you just need to use a SQL extension that isn’t supported by SQLAlchemy.

Acoustid database dump available

I’ve finally written a script to take a consistent dump of the Acoustid database in the PostgreSQL tab-separated format used by the COPY command. I do not have any tools for importing it into PostgreSQL, so it has to be done manually by running SQL commands, but if anybody is interested in playing with the database, you can download it here (2.7G after compression using bzip2, 6.4G uncompressed). The data is licensed under a Creative Commons BY-SA 3.0 License. I’ll add a cron job to export the database at the beginning of every month.

MusicBrainz database replication

I wanted to work on the Acoustid lookup web service and for this I needed to setup a MusicBrainz replicated database slave. Normally I’d use the Perl code from mb_server, but I didn’t want to mess up the setup I have on the machine hosting acoustid.org with CPAN packages. I had a plan to write a non-Perl version of the replicated code earlier, but only yesterday I really needed it. It turned out to be easier than I expected, so I already have a working version that I use to update my local MB database. Get it from GitHub, if you would like to give it a try.

Oracle…

Working with Oracle is always an adventure. The error messages are usually not very helpful, so you have to guess a lot. What I’ve seen today is an extreme though. Oracle allows you to create a table with a column named “TIMESTAMP” if you quote it:

UUID generator in PL/pgSQL

While writing an SQL script to upgrade the MusicBrainz database for the last release, I needed a way to generate new UUIDs from SQL. PostgreSQL has a native UUID data type and a contrib module for generating UUIDs since version 8.3, but this wouldn’t help me, because I needed it to work with at least version 8.1. I had this idea to write PL/pgSQL functions to generate UUIDs, so I skimmer over the RFC 4122 that documents them and found out that it isn’t actually that hard.

Back to Top ↑

postgresql

Easier MusicBrainz NGS database setup

Some time ago I wrote a couple of tools that help me set up and update a mirror of the MusicBrainz database on the Acoustid server. It turned out to be work really well. Recently I’ve seen a few people struggling with setting up the NGS database using the original server codebase. The official route assumes you are going to run a MB server instance, which makes things a little bit more complicated than it has to be. You have to install a number Perl modules, you have to compile the MusicBrainz-specific PostgreSQL extensions, even though you most likely don’t need them, you are forced to setup a musicbrainz_db_raw database that you are definitely not going to use, because there is no data in it, etc.

Acoustid database dump available

I’ve finally written a script to take a consistent dump of the Acoustid database in the PostgreSQL tab-separated format used by the COPY command. I do not have any tools for importing it into PostgreSQL, so it has to be done manually by running SQL commands, but if anybody is interested in playing with the database, you can download it here (2.7G after compression using bzip2, 6.4G uncompressed). The data is licensed under a Creative Commons BY-SA 3.0 License. I’ll add a cron job to export the database at the beginning of every month.

MusicBrainz database replication

I wanted to work on the Acoustid lookup web service and for this I needed to setup a MusicBrainz replicated database slave. Normally I’d use the Perl code from mb_server, but I didn’t want to mess up the setup I have on the machine hosting acoustid.org with CPAN packages. I had a plan to write a non-Perl version of the replicated code earlier, but only yesterday I really needed it. It turned out to be easier than I expected, so I already have a working version that I use to update my local MB database. Get it from GitHub, if you would like to give it a try.

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

UUID generator in PL/pgSQL

While writing an SQL script to upgrade the MusicBrainz database for the last release, I needed a way to generate new UUIDs from SQL. PostgreSQL has a native UUID data type and a contrib module for generating UUIDs since version 8.3, but this wouldn’t help me, because I needed it to work with at least version 8.1. I had this idea to write PL/pgSQL functions to generate UUIDs, so I skimmer over the RFC 4122 that documents them and found out that it isn’t actually that hard.

Back to Top ↑

linux

Dropbox folder icon in GNOME 3

I upgraded to GNOME 3 just over a week ago and when installing the Feanza icon theme, I noticed that there is a nice Dropbox folder icon included. Nautilus allows you to set icon for any folder, but only lets you select a specific image file, which doesn’t look particularly good when scaled.

Custom file associations on GNOME

It seems that there is no GUI method settings associations for custom files in GNOME. I’ve had this problem before with dbmodel before. It writes save its data in XML files that end with the extension “.dmf”. The problem is that GNOME’s file associations work with MIME types and by default GNOME doesn’t know anything about these silly .dmf files, it only sees XML files, so if I want to automatically open .dmf files with dbmodel, I can either set it for all XML files or for nothing. I eventually gave up on trying to do this, but since I started to use eMusic and switched to Chrome, it become much more annoying.

Resizing a LVM swap volume

Another post mainly for myself, just so I know where to find the information quickly the next time I need it. If you have swap on a LVM volume, these commands can be used to resize it (in this case, increase by 100MB):

Where is my one gig of RAM?

I got a new laptop last week and it came with an extra RAM module. I thought it would be fun to have more RAM in laptop than I have in my desktop machine, so I put it in and to my surprise Ubuntu was reporting only 3GB of RAM, even though the machine had 2x2GB modules. I checked BIOS and it correctly said the machine has 4GB of RAM. It turns out that on a 32-bit machine you can address only 3GB using the standard addressing method.  There is an extension to work it around, called PAE, but the default Linux kernel in Ubuntu has it disabled. I was afraid I’d have to compile my own kernel, but fortunately there is a package with PAE enabled, so I only had to do:

Back to Top ↑

fail

Oracle…

Working with Oracle is always an adventure. The error messages are usually not very helpful, so you have to guess a lot. What I’ve seen today is an extreme though. Oracle allows you to create a table with a column named “TIMESTAMP” if you quote it:

Fun with timestamps

Some programming languages really encourage using UNIX timestamps for working with dates. PHP is a good example of such a language. Functions like date, strtotime, strftime are used all the time. Most people don’t realize that timestamps in general can’t really be used for calculations though. The problem is that most countries use daylight saving time, which means that two times a year the local timezone changes. This nicely breaks the assumption that every day has 24 hours. It doesn’t. Sometimes it has 23 or 25 hours.

Mercurial, part 1

I’ve been using Mercurial at work for two months now and the expectations I had about it didn’t change to anything better. I guess it looks cool for people who are used to SVN, or even CVS, and are not familiar with other DVCS. I must say that as a Bazaar user, I miss a lot of things. There are some that can be worked around, for something you just have to be extra careful and for something you are out of luck. I really don’t get how people use Mercurial for managing large projects.

Technical book authors

To be honest, I don’t read technical books much. I prefer reading the official documentation for a product I need to work with, or use some other ways to get information about it. I always assumed people who write such books are experts though. There are many book authors on Stack Overflow, but today I encountered a particularly interesting situation with one of them.

Disabling sound in GDM

I often have to turn on my laptop in a situation when I need it to be quiet. It’s easy to disable the login sound in GNOME, but in the new Ubuntu release it became quite hard to disable the GDM startup sound. Previously it was possible to simply use gdmsetup to change the sound, themes, etc. However, in recent versions of GDM (like the one included in Ubuntu 9.10), the window was reduced to a question whether it should log me in automatically or ask for the password. The old configuration file gdm.conf is also gone, replaced with GConf-based configuration. The GDM documentation says, as an example, that sound can be disabled by changing the /apps/gdm/simple-greeter/settings-manager-plugins/sound/active GConf key, so I tried to set it to false, but that didn’t help. I’ve managed to fix it eventually, thanks to a Ubuntu bug, where somebody mentions the /desktop/gnome/sound/event_sounds key.

Back to Top ↑

programming

My AI helpers, CodeRabbit and SourceGraph Cody

I’ve been an early adopter of AI coding tools. I’ve been using GitHub Copilot from the technical preview stages in 2021. It was mind-blowing to me. The interface was pretty minimal compared to what we have now, but even at the stage, it was revolutionizing the way I work. I’ve dreamed for a long time about programming without having to actually write all the code, and it was starting to become a reality. All in all, I was pretty happy with it.

Msgpack serialization library for Zig

I’ve been playing with Zig over the last few weeks. The language had been on my radar for a long time, since it was originally developed for writing audio software, but I never paid too much attention to it. It seems that it’s becoming more popular, so I’ve decided to learn it and picked a small task of rewriting the AcoustID fingerprint index server in it. That is still in progress, but there is one side product that is almost ready, a library for handling msgpack serialization.

Job interviews

I have been looking for a new position for a few weeks now. For the first time in my life, I’m trying to be more selective about what I do, so I went through a couple of interviews. I have come to realization that I’m unlikely to ever work on a good position for a larger company, that actually has some “hiring process”. The reason for that is that I’m just not built for job interviews. At all.

Audio-only FFmpeg binary builds

A side-effect of the new build system for Chromaprint releases is that now I have clean builds of FFmpeg available. Some people have asked me about this in the past, so I thought I’d make them publicly available.

Back to Top ↑

bzr

“Punchcard” graphs for Bazaar

GitHub has a nice feature called “Punchcard”. It’s a graph that represents numbers of commits by day and hour (example). You can easily see wherether a project was hacked over weekends or nights, if it’s done by full-time employees, etc. There are two problems though:

Bazaar commit metadata

I maintain a few open source projects that use SVN, so notes like “Fixes bug #123, patch by J. Random Hacker” in commit messages are more than usual. When I started using Bazaar for Picard, I thought it would be nice to handle these natively. Bazaar could store bug metadata since version 0.16, using the bzr commit --fixes option, so that was nice. It kind of inspired me to add the other part, the author name, which was a little more important for me than bug numbers. I wanted contributors who send plain patches to be equally credited for their work in the default branch viewing tools. I knew that Git had the concept of separated “committer” and “change author” and I really liked the idea, so I submitted a patch to Bazaar to add something similar (that was in bzr 0.91). The change allows you specify the author name on commit, that would be stored along in the revision along with the committer name. So you can run a command like this:

Working with branches in Bazaar

Many people dislike the directory-per-branch concept that Bazaar uses. What they don’t realize though, is that this doesn’t mean you need to have a working tree for each branch. You can very easily simulate cheap Git-style branches, but with some added flexibility. Checkouts are a fairly well known feature of Bazaar, but people mostly associate it with the centralized workflow (i.e. checking out remote branches). This is not the only use case for them.

Back to Top ↑

gnome

Dropbox folder icon in GNOME 3

I upgraded to GNOME 3 just over a week ago and when installing the Feanza icon theme, I noticed that there is a nice Dropbox folder icon included. Nautilus allows you to set icon for any folder, but only lets you select a specific image file, which doesn’t look particularly good when scaled.

Custom file associations on GNOME

It seems that there is no GUI method settings associations for custom files in GNOME. I’ve had this problem before with dbmodel before. It writes save its data in XML files that end with the extension “.dmf”. The problem is that GNOME’s file associations work with MIME types and by default GNOME doesn’t know anything about these silly .dmf files, it only sees XML files, so if I want to automatically open .dmf files with dbmodel, I can either set it for all XML files or for nothing. I eventually gave up on trying to do this, but since I started to use eMusic and switched to Chrome, it become much more annoying.

Tomboy’s “Start Here” note

I use Dropbox to synchronize my Tomboy notes. This works very well, but there is a problem when setting it up on a new computer. Tomboy has a special “Start Here” note, which is used mainly for organizing other notes. When I tell it to synchronize notes from the Dropbox directory and overwrite the existing default notes, it will do so, but it doesn’t change it’s “Start Here” note pointer. As as result, Tomboy is not aware that my new Start Here note is the one it should use. As far as I know, there is no way fix this using Tomboy itself. It can be done only using GConf. Here is an example how to do it from the command line:

Disabling sound in GDM

I often have to turn on my laptop in a situation when I need it to be quiet. It’s easy to disable the login sound in GNOME, but in the new Ubuntu release it became quite hard to disable the GDM startup sound. Previously it was possible to simply use gdmsetup to change the sound, themes, etc. However, in recent versions of GDM (like the one included in Ubuntu 9.10), the window was reduced to a question whether it should log me in automatically or ask for the password. The old configuration file gdm.conf is also gone, replaced with GConf-based configuration. The GDM documentation says, as an example, that sound can be disabled by changing the /apps/gdm/simple-greeter/settings-manager-plugins/sound/active GConf key, so I tried to set it to false, but that didn’t help. I’ve managed to fix it eventually, thanks to a Ubuntu bug, where somebody mentions the /desktop/gnome/sound/event_sounds key.

Back to Top ↑

github

AcoustID code moved to Bitbucket

I was not very happy when GitHub announced that it discontinues project downloads. I was using GitHub to host compiled packages for Chromaprint and the AcoustID fingerprinter, as well as release tarballs for all AcoustID projects, so I had to start looking for alternatives.

TagLib 1.7 released

TagLib 1.7 has been released. This release adds support for Monkey’s Audio files and cover art reading/writing for WMA and FLAC files. There is also a number of bug fixes, more details in the changelog. There are two important changes associated with this release:

“Punchcard” graphs for Bazaar

GitHub has a nice feature called “Punchcard”. It’s a graph that represents numbers of commits by day and hour (example). You can easily see wherether a project was hacked over weekends or nights, if it’s done by full-time employees, etc. There are two problems though:

Back to Top ↑

audio

How does Chromaprint work?

I’ve been meaning to write this post for a long time, but never really finished it. I hope it will help people understand how does the Chromaprint algorithm work, where do the individual ideas come from and what do the fingerprints really represent. It’s not meant to be a detailed description, just the basics to get the general idea.

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

Introducing Chromaprint

After several months of reading research papers, learning and weekend coding, I’m very happy to make the half-finished code of my audio fingerprinting library public. :) I’m doing this mostly for selfish reasons, because it will force me to stop thinking in “hacker mode” and hopefully properly finish it, and I also hope to get some help and feedback from other people. There is nothing for regular users yet though, just for developers or people not afraid of the command line.

Back to Top ↑

git

AcoustID code moved to Bitbucket

I was not very happy when GitHub announced that it discontinues project downloads. I was using GitHub to host compiled packages for Chromaprint and the AcoustID fingerprinter, as well as release tarballs for all AcoustID projects, so I had to start looking for alternatives.

TagLib 1.7 released

TagLib 1.7 has been released. This release adds support for Monkey’s Audio files and cover art reading/writing for WMA and FLAC files. There is also a number of bug fixes, more details in the changelog. There are two important changes associated with this release:

Back to Top ↑

rant

Goodbye, Google Chrome

I’ve upgraded my laptop today, that included Google Chrome, and surprise, surprise, when it restarted, it started telling me that the uBlock Origin extension is no longer supported and will be disabled. I’m paying for YouTube Premium, but I still can’t live without ad blocker. It turns out you can just enable the extension again and it will keep working, but for how long. So I decide to switch. I’ve been using Chrome from the very early times, long before it was mainstream. The more popular Chrome was, the more hostile Google was. Now removing my ad blocker, that’s just saying they don’t want me to use their browser. That’s OK, now we have alternatives, even with ad blockers built in. My first choice would have been Opera, but unfortunately 1Password doesn’t support it, so I went to the next best option, Brave. So far, I’m pretty happy with it.

Technical book authors

To be honest, I don’t read technical books much. I prefer reading the official documentation for a product I need to work with, or use some other ways to get information about it. I always assumed people who write such books are experts though. There are many book authors on Stack Overflow, but today I encountered a particularly interesting situation with one of them.

Stack Overflow Careers

When I have some free time and I’m bored, I try to help people at Stack Overflow.  Recently the owners of Stack Overflow launched a site where you can post your CV, which are linked to your Stack Overflow account, and companies can search them. Nice idea. But the business model behind it makes it horrible. This blog post by Joel Spolsky actually made me write this rant. Stack Overflow is obviously doing very good at getting money from ads. People answering questions over there actually make them money, as they increase the value of the site. (They still display ads even to those people, which is something I also don’t get, but with Adblock Plus, I don’t care.) The thing is that they charge job seekers for having their CV searchable within the site. The official reason for that is that they want to ensure that everybody who has their CV listed there is actively looking for a job. If that’s so, why are they raising the price from $29 to $99? $29 should do just as well for filtering the people who post their CV “just because they can”. I have real trouble imagining any competent programmer (who actively contributes to Stack Overflow, therefore makes sure they get their ad revenue) would want to pay to get his CV listed on the site. It’s not about the money though, it’s about the principle. I wouldn’t pay for such a service, just like I wouldn’t send my CV to a recruitment agency.

Back to Top ↑

stackoverflow

Fun with timestamps

Some programming languages really encourage using UNIX timestamps for working with dates. PHP is a good example of such a language. Functions like date, strtotime, strftime are used all the time. Most people don’t realize that timestamps in general can’t really be used for calculations though. The problem is that most countries use daylight saving time, which means that two times a year the local timezone changes. This nicely breaks the assumption that every day has 24 hours. It doesn’t. Sometimes it has 23 or 25 hours.

Technical book authors

To be honest, I don’t read technical books much. I prefer reading the official documentation for a product I need to work with, or use some other ways to get information about it. I always assumed people who write such books are experts though. There are many book authors on Stack Overflow, but today I encountered a particularly interesting situation with one of them.

Stack Overflow Careers

When I have some free time and I’m bored, I try to help people at Stack Overflow.  Recently the owners of Stack Overflow launched a site where you can post your CV, which are linked to your Stack Overflow account, and companies can search them. Nice idea. But the business model behind it makes it horrible. This blog post by Joel Spolsky actually made me write this rant. Stack Overflow is obviously doing very good at getting money from ads. People answering questions over there actually make them money, as they increase the value of the site. (They still display ads even to those people, which is something I also don’t get, but with Adblock Plus, I don’t care.) The thing is that they charge job seekers for having their CV searchable within the site. The official reason for that is that they want to ensure that everybody who has their CV listed there is actively looking for a job. If that’s so, why are they raising the price from $29 to $99? $29 should do just as well for filtering the people who post their CV “just because they can”. I have real trouble imagining any competent programmer (who actively contributes to Stack Overflow, therefore makes sure they get their ad revenue) would want to pay to get his CV listed on the site. It’s not about the money though, it’s about the principle. I wouldn’t pay for such a service, just like I wouldn’t send my CV to a recruitment agency.

Back to Top ↑

picard

Daily Picard builds for Windows

Building the Windows installer of MusicBrainz Picard has always been problematic. I never had the process automated, it always involved a lot of manual steps which I could never remember. And because Picard releases do not happen very often, it was not very easy for people to test with the latest version on Windows (which usually included a number of fixes.

Picard 0.13 released

MusicBrainz Picard wasn’t under active development for a long time. In fact, the last release was in November 2009. Even due to the situation, some bug fixes accumulated in the source control repository over the time, so the primary goal of this release is to publish these bug fixes. There were also a few larger patches, such us the sorting support by Aaron Lambers, but these are not included in this release. I’m hoping that patches like that will get committed now that 0.13 is released and a new release will follow in less than a year from now. :)

“Punchcard” graphs for Bazaar

GitHub has a nice feature called “Punchcard”. It’s a graph that represents numbers of commits by day and hour (example). You can easily see wherether a project was hacked over weekends or nights, if it’s done by full-time employees, etc. There are two problems though:

Back to Top ↑

java

Closure Templates (Soy) for Python

For the past two weeks I’ve been adding a Python backend to Google’s Closure Templates. The work is now almost finished, so I’m happy to release a preview version of the Soy-to-Python compiler with a runtime Python library (closure-templates-for-python) and a Flask extension (Flask-Soy), to make it possible to work with Soy templates from Python.

Acoustid

After asking for fingerprint test data in my last post about Chromaprint I received about 270k fingerprints from. This helped me to perform some larger tests on the proof-of-concept lookup server I had implemented using Java and PostgreSQL. I had to do some technical changes, but the main idea seemed to work pretty well. I wasn’t sure about this when I was working on Chromaprint, but now I believe that I can realistically run an audio recognition service.

Back to Top ↑

cmake

Minimal Qt/CMake template

I’m starting working on the GUI submission tool for Acoustid and I wanted to use CMake instead of qmake for building the application. I couldn’t find anywhere a simple example of what do I have to put into my CMakeLists.txt in order to build a Qt application while correctly handling all moc files, ui files and resources.

Cross-compiling with CMake and Autotools

[The last time]/2010/07/introducing-chromaprint/) I needed to build a Windows binary, I found it easier to cross-compile it from Linux than to setup a development environment on a freshly installed Windows machine. The problem is that even though it’s not hard, you need to remember some obscure options. Today I needed to build a new version of ISRCsubmit and I had to search for the recipe again. So, let’s document it somewhere I can find it in the future…

Back to Top ↑

windows

Cross-compiling with CMake and Autotools

[The last time]/2010/07/introducing-chromaprint/) I needed to build a Windows binary, I found it easier to cross-compile it from Linux than to setup a development environment on a freshly installed Windows machine. The problem is that even though it’s not hard, you need to remember some obscure options. Today I needed to build a new version of ISRCsubmit and I had to search for the recipe again. So, let’s document it somewhere I can find it in the future…

Back to Top ↑

javascript

Closure Templates (Soy) for Python

For the past two weeks I’ve been adding a Python backend to Google’s Closure Templates. The work is now almost finished, so I’m happy to release a preview version of the Soy-to-Python compiler with a runtime Python library (closure-templates-for-python) and a Flask extension (Flask-Soy), to make it possible to work with Soy templates from Python.

Playing with IRCCloud…

Yesterday I got my invite to IRCCloud, which is a web-based IRC client, but unlike other similar clients, the IRC connection is on the server, so I stay connected even when I close my browser. The first thing I had trouble with, after switching from a customized IRSSI, was that all nicknames had the same color. I never realized how much I rely on nickname colors, but it seems that I’m too lazy to read the nicknames. I wanted to try writing some user scripts for Chrome and this seemed like a nice opportunity. I stole the coloring algorithm from MusicBrainz’ chat logs and wrote this little script, which automatically sets a different color for nicknames in IRCCloud:

Back to Top ↑

zig

Six months of yak shaving a Zig web backend stack

A while back I wrote about Zio, my async I/O library for Zig. At the end of that post I said the next step was to update my NATS client and write an HTTP server. Well, one thing led to another, and I now have a whole web backend stack written entirely in Zig.

How I turned Zig into my favorite language to write network programs in

I’ve been watching the Zig language for a while now, given that it was created for writing audio software (low-level, no allocations, real time). I never paid too much attention though, it seemed a little weird to me and I didn’t see the real need. Then I saw a post from Andrew Kelley (creator of the language) on Hacker News, about how he reimplemented my Chromaprint algorithm in Zig, and that got me really interested.

Msgpack serialization library for Zig

I’ve been playing with Zig over the last few weeks. The language had been on my radar for a long time, since it was originally developed for writing audio software, but I never paid too much attention to it. It seems that it’s becoming more popular, so I’ve decided to learn it and picked a small task of rewriting the AcoustID fingerprint index server in it. That is still in progress, but there is one side product that is almost ready, a library for handling msgpack serialization.

Back to Top ↑

sql

Extending the SQLAlchemy SQL expression language

The SQL expression language from SQLAlchemy is already very flexible and allows you to build almost any standard SQL query, but sometimes you just need to use a SQL extension that isn’t supported by SQLAlchemy.

UUID generator in PL/pgSQL

While writing an SQL script to upgrade the MusicBrainz database for the last release, I needed a way to generate new UUIDs from SQL. PostgreSQL has a native UUID data type and a contrib module for generating UUIDs since version 8.3, but this wouldn’t help me, because I needed it to work with at least version 8.1. I had this idea to write PL/pgSQL functions to generate UUIDs, so I skimmer over the RFC 4122 that documents them and found out that it isn’t actually that hard.

Back to Top ↑

bazaar

Bazaar commit metadata

I maintain a few open source projects that use SVN, so notes like “Fixes bug #123, patch by J. Random Hacker” in commit messages are more than usual. When I started using Bazaar for Picard, I thought it would be nice to handle these natively. Bazaar could store bug metadata since version 0.16, using the bzr commit --fixes option, so that was nice. It kind of inspired me to add the other part, the author name, which was a little more important for me than bug numbers. I wanted contributors who send plain patches to be equally credited for their work in the default branch viewing tools. I knew that Git had the concept of separated “committer” and “change author” and I really liked the idea, so I submitted a patch to Bazaar to add something similar (that was in bzr 0.91). The change allows you specify the author name on commit, that would be stored along in the revision along with the committer name. So you can run a command like this:

Working with branches in Bazaar

Many people dislike the directory-per-branch concept that Bazaar uses. What they don’t realize though, is that this doesn’t mean you need to have a working tree for each branch. You can very easily simulate cheap Git-style branches, but with some added flexibility. Checkouts are a fairly well known feature of Bazaar, but people mostly associate it with the centralized workflow (i.e. checking out remote branches). This is not the only use case for them.

Back to Top ↑

twisted

Twisted Trial and Jenkins

It’s not completely obvious how to configure a Twisted-based job that uses Trial for running tests in Jenkins, so hopefully this post will save somebody a little time in the future.

“MySQL server has gone away”

I have written a few Twisted scripts at work that parse incoming data from a socket and save it in a MySQL database, using the MySQLdb package. It’s a well-known fact that the MySQL server will close connections that are inactive for some time and yet I forgot to handle it in last script I wrote. Previously I solved the problem by remembering the last time I used the connection and forcing a reconnect based on this value or the recycle option in SQLAlchemy’s connection pool when I needed a connection pool (which does basically the same as the former). But when I found the problem in the latest script today, I thought I should finally solved it properly, so I started Googling…

Back to Top ↑

qstring

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

ubuntu

Disabling sound in GDM

I often have to turn on my laptop in a situation when I need it to be quiet. It’s easy to disable the login sound in GNOME, but in the new Ubuntu release it became quite hard to disable the GDM startup sound. Previously it was possible to simply use gdmsetup to change the sound, themes, etc. However, in recent versions of GDM (like the one included in Ubuntu 9.10), the window was reduced to a question whether it should log me in automatically or ask for the password. The old configuration file gdm.conf is also gone, replaced with GConf-based configuration. The GDM documentation says, as an example, that sound can be disabled by changing the /apps/gdm/simple-greeter/settings-manager-plugins/sound/active GConf key, so I tried to set it to false, but that didn’t help. I’ve managed to fix it eventually, thanks to a Ubuntu bug, where somebody mentions the /desktop/gnome/sound/event_sounds key.

Where is my one gig of RAM?

I got a new laptop last week and it came with an extra RAM module. I thought it would be fun to have more RAM in laptop than I have in my desktop machine, so I put it in and to my surprise Ubuntu was reporting only 3GB of RAM, even though the machine had 2x2GB modules. I checked BIOS and it correctly said the machine has 4GB of RAM. It turns out that on a 32-bit machine you can address only 3GB using the standard addressing method.  There is an extension to work it around, called PAE, but the default Linux kernel in Ubuntu has it disabled. I was afraid I’d have to compile my own kernel, but fortunately there is a package with PAE enabled, so I only had to do:

Back to Top ↑

qbzr

“Punchcard” graphs for Bazaar

GitHub has a nice feature called “Punchcard”. It’s a graph that represents numbers of commits by day and hour (example). You can easily see wherether a project was hacked over weekends or nights, if it’s done by full-time employees, etc. There are two problems though:

Bazaar commit metadata

I maintain a few open source projects that use SVN, so notes like “Fixes bug #123, patch by J. Random Hacker” in commit messages are more than usual. When I started using Bazaar for Picard, I thought it would be nice to handle these natively. Bazaar could store bug metadata since version 0.16, using the bzr commit --fixes option, so that was nice. It kind of inspired me to add the other part, the author name, which was a little more important for me than bug numbers. I wanted contributors who send plain patches to be equally credited for their work in the default branch viewing tools. I knew that Git had the concept of separated “committer” and “change author” and I really liked the idea, so I submitted a patch to Bazaar to add something similar (that was in bzr 0.91). The change allows you specify the author name on commit, that would be stored along in the revision along with the committer name. So you can run a command like this:

Back to Top ↑

job

Job interviews

I have been looking for a new position for a few weeks now. For the first time in my life, I’m trying to be more selective about what I do, so I went through a couple of interviews. I have come to realization that I’m unlikely to ever work on a good position for a larger company, that actually has some “hiring process”. The reason for that is that I’m just not built for job interviews. At all.

Stack Overflow Careers

When I have some free time and I’m bored, I try to help people at Stack Overflow.  Recently the owners of Stack Overflow launched a site where you can post your CV, which are linked to your Stack Overflow account, and companies can search them. Nice idea. But the business model behind it makes it horrible. This blog post by Joel Spolsky actually made me write this rant. Stack Overflow is obviously doing very good at getting money from ads. People answering questions over there actually make them money, as they increase the value of the site. (They still display ads even to those people, which is something I also don’t get, but with Adblock Plus, I don’t care.) The thing is that they charge job seekers for having their CV searchable within the site. The official reason for that is that they want to ensure that everybody who has their CV listed there is actively looking for a job. If that’s so, why are they raising the price from $29 to $99? $29 should do just as well for filtering the people who post their CV “just because they can”. I have real trouble imagining any competent programmer (who actively contributes to Stack Overflow, therefore makes sure they get their ad revenue) would want to pay to get his CV listed on the site. It’s not about the money though, it’s about the principle. I wouldn’t pay for such a service, just like I wouldn’t send my CV to a recruitment agency.

Back to Top ↑

dropbox

Dropbox folder icon in GNOME 3

I upgraded to GNOME 3 just over a week ago and when installing the Feanza icon theme, I noticed that there is a nice Dropbox folder icon included. Nautilus allows you to set icon for any folder, but only lets you select a specific image file, which doesn’t look particularly good when scaled.

Tomboy’s “Start Here” note

I use Dropbox to synchronize my Tomboy notes. This works very well, but there is a problem when setting it up on a new computer. Tomboy has a special “Start Here” note, which is used mainly for organizing other notes. When I tell it to synchronize notes from the Dropbox directory and overwrite the existing default notes, it will do so, but it doesn’t change it’s “Start Here” note pointer. As as result, Tomboy is not aware that my new Start Here note is the one it should use. As far as I know, there is no way fix this using Tomboy itself. It can be done only using GConf. Here is an example how to do it from the command line:

Back to Top ↑

oracle

Extending the SQLAlchemy SQL expression language

The SQL expression language from SQLAlchemy is already very flexible and allows you to build almost any standard SQL query, but sometimes you just need to use a SQL extension that isn’t supported by SQLAlchemy.

Oracle…

Working with Oracle is always an adventure. The error messages are usually not very helpful, so you have to guess a lot. What I’ve seen today is an extreme though. Oracle allows you to create a table with a column named “TIMESTAMP” if you quote it:

Back to Top ↑

c++

Chromaprint plug-in for GStreamer

It’s been a long time since I learned some new framework (or even wrote some real code), so I decided to write a GStreamer plug-in that will wrap libchromaprint and make it very easy to generate Chromaprint fingerprints in GStreamer applications. This was inspired by a similar plug-in that Milosz Derezynski wrote for MusicDNS/libofa (the plug-in is now integrated in the official GStreamer distribution). Using the code from gst-ofa and gst-template, it turned out to be pretty easy. After a couple of hours, I was able to run commands like this and get valid fingerprints:

Introducing Chromaprint

After several months of reading research papers, learning and weekend coding, I’m very happy to make the half-finished code of my audio fingerprinting library public. :) I’m doing this mostly for selfish reasons, because it will force me to stop thinking in “hacker mode” and hopefully properly finish it, and I also hope to get some help and feedback from other people. There is nothing for regular users yet though, just for developers or people not afraid of the command line.

Back to Top ↑

cross-compile

Cross-compiling with CMake and Autotools

[The last time]/2010/07/introducing-chromaprint/) I needed to build a Windows binary, I found it easier to cross-compile it from Linux than to setup a development environment on a freshly installed Windows machine. The problem is that even though it’s not hard, you need to remember some obscure options. Today I needed to build a new version of ISRCsubmit and I had to search for the recipe again. So, let’s document it somewhere I can find it in the future…

Back to Top ↑

mingw

Cross-compiling with CMake and Autotools

[The last time]/2010/07/introducing-chromaprint/) I needed to build a Windows binary, I found it easier to cross-compile it from Linux than to setup a development environment on a freshly installed Windows machine. The problem is that even though it’s not hard, you need to remember some obscure options. Today I needed to build a new version of ISRCsubmit and I had to search for the recipe again. So, let’s document it somewhere I can find it in the future…

Back to Top ↑

qt

Minimal Qt/CMake template

I’m starting working on the GUI submission tool for Acoustid and I wanted to use CMake instead of qmake for building the application. I couldn’t find anywhere a simple example of what do I have to put into my CMakeLists.txt in order to build a Qt application while correctly handling all moc files, ui files and resources.

Back to Top ↑

replication

Easier MusicBrainz NGS database setup

Some time ago I wrote a couple of tools that help me set up and update a mirror of the MusicBrainz database on the Acoustid server. It turned out to be work really well. Recently I’ve seen a few people struggling with setting up the NGS database using the original server codebase. The official route assumes you are going to run a MB server instance, which makes things a little bit more complicated than it has to be. You have to install a number Perl modules, you have to compile the MusicBrainz-specific PostgreSQL extensions, even though you most likely don’t need them, you are forced to setup a musicbrainz_db_raw database that you are definitely not going to use, because there is no data in it, etc.

MusicBrainz database replication

I wanted to work on the Acoustid lookup web service and for this I needed to setup a MusicBrainz replicated database slave. Normally I’d use the Perl code from mb_server, but I didn’t want to mess up the setup I have on the machine hosting acoustid.org with CPAN packages. I had a plan to write a non-Perl version of the replicated code earlier, but only yesterday I really needed it. It turned out to be easier than I expected, so I already have a working version that I use to update my local MB database. Get it from GitHub, if you would like to give it a try.

Back to Top ↑

compile

Back to Top ↑

ffmpeg

Audio-only FFmpeg binary builds

A side-effect of the new build system for Chromaprint releases is that now I have clean builds of FFmpeg available. Some people have asked me about this in the past, so I thought I’d make them publicly available.

Back to Top ↑

about-me

Job interviews

I have been looking for a new position for a few weeks now. For the first time in my life, I’m trying to be more selective about what I do, so I went through a couple of interviews. I have come to realization that I’m unlikely to ever work on a good position for a larger company, that actually has some “hiring process”. The reason for that is that I’m just not built for job interviews. At all.

My story (as a programmer)

I started writing this as a bit longer bio blurb for the About page, but somehow it got too long before I was even halfway finished, so I decided to edit it a little bit and put it here instead. Not the usual stuff I post here, but not many people know how I got into programming and didn’t have the heart to just delete it. :)

Back to Top ↑

personal

Job interviews

I have been looking for a new position for a few weeks now. For the first time in my life, I’m trying to be more selective about what I do, so I went through a couple of interviews. I have come to realization that I’m unlikely to ever work on a good position for a larger company, that actually has some “hiring process”. The reason for that is that I’m just not built for job interviews. At all.

My story (as a programmer)

I started writing this as a bit longer bio blurb for the About page, but somehow it got too long before I was even halfway finished, so I decided to edit it a little bit and put it here instead. Not the usual stuff I post here, but not many people know how I got into programming and didn’t have the heart to just delete it. :)

Back to Top ↑

jenkins

Daily Picard builds for Windows

Building the Windows installer of MusicBrainz Picard has always been problematic. I never had the process automated, it always involved a lot of manual steps which I could never remember. And because Picard releases do not happen very often, it was not very easy for people to test with the latest version on Windows (which usually included a number of fixes.

Twisted Trial and Jenkins

It’s not completely obvious how to configure a Twisted-based job that uses Trial for running tests in Jenkins, so hopefully this post will save somebody a little time in the future.

Back to Top ↑

networking

Six months of yak shaving a Zig web backend stack

A while back I wrote about Zio, my async I/O library for Zig. At the end of that post I said the next step was to update my NATS client and write an HTTP server. Well, one thing led to another, and I now have a whole web backend stack written entirely in Zig.

How I turned Zig into my favorite language to write network programs in

I’ve been watching the Zig language for a while now, given that it was created for writing audio software (low-level, no allocations, real time). I never paid too much attention though, it seemed a little weird to me and I didn’t see the real need. Then I saw a post from Andrew Kelley (creator of the language) on Hacker News, about how he reimplemented my Chromaprint algorithm in Zig, and that got me really interested.

Back to Top ↑

async

Six months of yak shaving a Zig web backend stack

A while back I wrote about Zio, my async I/O library for Zig. At the end of that post I said the next step was to update my NATS client and write an HTTP server. Well, one thing led to another, and I now have a whole web backend stack written entirely in Zig.

How I turned Zig into my favorite language to write network programs in

I’ve been watching the Zig language for a while now, given that it was created for writing audio software (low-level, no allocations, real time). I never paid too much attention though, it seemed a little weird to me and I didn’t see the real need. Then I saw a post from Andrew Kelley (creator of the language) on Hacker News, about how he reimplemented my Chromaprint algorithm in Zig, and that got me really interested.

Back to Top ↑

plpgsql

UUID generator in PL/pgSQL

While writing an SQL script to upgrade the MusicBrainz database for the last release, I needed a way to generate new UUIDs from SQL. PostgreSQL has a native UUID data type and a contrib module for generating UUIDs since version 8.3, but this wouldn’t help me, because I needed it to work with at least version 8.1. I had this idea to write PL/pgSQL functions to generate UUIDs, so I skimmer over the RFC 4122 that documents them and found out that it isn’t actually that hard.

Back to Top ↑

uuid

UUID generator in PL/pgSQL

While writing an SQL script to upgrade the MusicBrainz database for the last release, I needed a way to generate new UUIDs from SQL. PostgreSQL has a native UUID data type and a contrib module for generating UUIDs since version 8.3, but this wouldn’t help me, because I needed it to work with at least version 8.1. I had this idea to write PL/pgSQL functions to generate UUIDs, so I skimmer over the RFC 4122 that documents them and found out that it isn’t actually that hard.

Back to Top ↑

ssh

Back to Top ↑

unix

Back to Top ↑

vcs

Working with branches in Bazaar

Many people dislike the directory-per-branch concept that Bazaar uses. What they don’t realize though, is that this doesn’t mean you need to have a working tree for each branch. You can very easily simulate cheap Git-style branches, but with some added flexibility. Checkouts are a fairly well known feature of Bazaar, but people mostly associate it with the centralized workflow (i.e. checking out remote branches). This is not the only use case for them.

Back to Top ↑

flac

TagLib 1.6.1

TagLib 1.6.1 has been released. It’s a minor bug-fix release. Main changes are content-based detection of .oga files, saving Vorbis Comments to Ogg FLAC files and support for cover art in MP4 files. Tarball is available here for now, later also on Scott’s page, and updated API docs are here.

Back to Top ↑

mp4

TagLib 1.6.1

TagLib 1.6.1 has been released. It’s a minor bug-fix release. Main changes are content-based detection of .oga files, saving Vorbis Comments to Ogg FLAC files and support for cover art in MP4 files. Tarball is available here for now, later also on Scott’s page, and updated API docs are here.

Back to Top ↑

oga

TagLib 1.6.1

TagLib 1.6.1 has been released. It’s a minor bug-fix release. Main changes are content-based detection of .oga files, saving Vorbis Comments to Ogg FLAC files and support for cover art in MP4 files. Tarball is available here for now, later also on Scott’s page, and updated API docs are here.

Back to Top ↑

ogg

TagLib 1.6.1

TagLib 1.6.1 has been released. It’s a minor bug-fix release. Main changes are content-based detection of .oga files, saving Vorbis Comments to Ogg FLAC files and support for cover art in MP4 files. Tarball is available here for now, later also on Scott’s page, and updated API docs are here.

Back to Top ↑

mysql

“MySQL server has gone away”

I have written a few Twisted scripts at work that parse incoming data from a socket and save it in a MySQL database, using the MySQLdb package. It’s a well-known fact that the MySQL server will close connections that are inactive for some time and yet I forgot to handle it in last script I wrote. Previously I solved the problem by remembering the last time I used the connection and forcing a reconnect based on this value or the recycle option in SQLAlchemy’s connection pool when I needed a connection pool (which does basically the same as the former). But when I found the problem in the latest script today, I thought I should finally solved it properly, so I started Googling…

Back to Top ↑

mysqldb

“MySQL server has gone away”

I have written a few Twisted scripts at work that parse incoming data from a socket and save it in a MySQL database, using the MySQLdb package. It’s a well-known fact that the MySQL server will close connections that are inactive for some time and yet I forgot to handle it in last script I wrote. Previously I solved the problem by remembering the last time I used the connection and forcing a reconnect based on this value or the recycle option in SQLAlchemy’s connection pool when I needed a connection pool (which does basically the same as the former). But when I found the problem in the latest script today, I thought I should finally solved it properly, so I started Googling…

Back to Top ↑

copy-on-write

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

hacks

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

performance

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

stl

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

string

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

wstring

Copy-on-write string performance

Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.

Back to Top ↑

memory

Where is my one gig of RAM?

I got a new laptop last week and it came with an extra RAM module. I thought it would be fun to have more RAM in laptop than I have in my desktop machine, so I put it in and to my surprise Ubuntu was reporting only 3GB of RAM, even though the machine had 2x2GB modules. I checked BIOS and it correctly said the machine has 4GB of RAM. It turns out that on a 32-bit machine you can address only 3GB using the standard addressing method.  There is an extension to work it around, called PAE, but the default Linux kernel in Ubuntu has it disabled. I was afraid I’d have to compile my own kernel, but fortunately there is a package with PAE enabled, so I only had to do:

Back to Top ↑

pae

Where is my one gig of RAM?

I got a new laptop last week and it came with an extra RAM module. I thought it would be fun to have more RAM in laptop than I have in my desktop machine, so I put it in and to my surprise Ubuntu was reporting only 3GB of RAM, even though the machine had 2x2GB modules. I checked BIOS and it correctly said the machine has 4GB of RAM. It turns out that on a 32-bit machine you can address only 3GB using the standard addressing method.  There is an extension to work it around, called PAE, but the default Linux kernel in Ubuntu has it disabled. I was afraid I’d have to compile my own kernel, but fortunately there is a package with PAE enabled, so I only had to do:

Back to Top ↑

ram

Where is my one gig of RAM?

I got a new laptop last week and it came with an extra RAM module. I thought it would be fun to have more RAM in laptop than I have in my desktop machine, so I put it in and to my surprise Ubuntu was reporting only 3GB of RAM, even though the machine had 2x2GB modules. I checked BIOS and it correctly said the machine has 4GB of RAM. It turns out that on a 32-bit machine you can address only 3GB using the standard addressing method.  There is an extension to work it around, called PAE, but the default Linux kernel in Ubuntu has it disabled. I was afraid I’d have to compile my own kernel, but fortunately there is a package with PAE enabled, so I only had to do:

Back to Top ↑

gconf

Disabling sound in GDM

I often have to turn on my laptop in a situation when I need it to be quiet. It’s easy to disable the login sound in GNOME, but in the new Ubuntu release it became quite hard to disable the GDM startup sound. Previously it was possible to simply use gdmsetup to change the sound, themes, etc. However, in recent versions of GDM (like the one included in Ubuntu 9.10), the window was reduced to a question whether it should log me in automatically or ask for the password. The old configuration file gdm.conf is also gone, replaced with GConf-based configuration. The GDM documentation says, as an example, that sound can be disabled by changing the /apps/gdm/simple-greeter/settings-manager-plugins/sound/active GConf key, so I tried to set it to false, but that didn’t help. I’ve managed to fix it eventually, thanks to a Ubuntu bug, where somebody mentions the /desktop/gnome/sound/event_sounds key.

Back to Top ↑

gdm

Disabling sound in GDM

I often have to turn on my laptop in a situation when I need it to be quiet. It’s easy to disable the login sound in GNOME, but in the new Ubuntu release it became quite hard to disable the GDM startup sound. Previously it was possible to simply use gdmsetup to change the sound, themes, etc. However, in recent versions of GDM (like the one included in Ubuntu 9.10), the window was reduced to a question whether it should log me in automatically or ask for the password. The old configuration file gdm.conf is also gone, replaced with GConf-based configuration. The GDM documentation says, as an example, that sound can be disabled by changing the /apps/gdm/simple-greeter/settings-manager-plugins/sound/active GConf key, so I tried to set it to false, but that didn’t help. I’ve managed to fix it eventually, thanks to a Ubuntu bug, where somebody mentions the /desktop/gnome/sound/event_sounds key.

Back to Top ↑

encoding

Back to Top ↑

filesystem

Back to Top ↑

unicode

Back to Top ↑

utf-8

Back to Top ↑

google

Redirect to Google’s OpenID

I’ve started using OpenID some time ago and I really like it. I was surprised that large companied like Google or Yahoo! are OpenID providers and that made me to try using Google’s OpenID. The first site I logged in to was Stack Overflow, which has nice buttons for major providers, so that was easy. The problem was when I first needed to log in to a site without such buttons. After some searching I’ve found out that the Google OpenID end-point is https://www.google.com/accounts/o8/id, but I had to search for it every single time I needed it. Every time I find it I think it shouldn’t not that hard to remember the URL, but the next time I need it I just can’t remember it.

Back to Top ↑

openid

Redirect to Google’s OpenID

I’ve started using OpenID some time ago and I really like it. I was surprised that large companied like Google or Yahoo! are OpenID providers and that made me to try using Google’s OpenID. The first site I logged in to was Stack Overflow, which has nice buttons for major providers, so that was easy. The problem was when I first needed to log in to a site without such buttons. After some searching I’ve found out that the Google OpenID end-point is https://www.google.com/accounts/o8/id, but I had to search for it every single time I needed it. Every time I find it I think it shouldn’t not that hard to remember the URL, but the next time I need it I just can’t remember it.

Back to Top ↑

xrds

Redirect to Google’s OpenID

I’ve started using OpenID some time ago and I really like it. I was surprised that large companied like Google or Yahoo! are OpenID providers and that made me to try using Google’s OpenID. The first site I logged in to was Stack Overflow, which has nice buttons for major providers, so that was easy. The problem was when I first needed to log in to a site without such buttons. After some searching I’ve found out that the Google OpenID end-point is https://www.google.com/accounts/o8/id, but I had to search for it every single time I needed it. Every time I find it I think it shouldn’t not that hard to remember the URL, but the next time I need it I just can’t remember it.

Back to Top ↑

lvextend

Resizing a LVM swap volume

Another post mainly for myself, just so I know where to find the information quickly the next time I need it. If you have swap on a LVM volume, these commands can be used to resize it (in this case, increase by 100MB):

Back to Top ↑

lvm

Resizing a LVM swap volume

Another post mainly for myself, just so I know where to find the information quickly the next time I need it. If you have swap on a LVM volume, these commands can be used to resize it (in this case, increase by 100MB):

Back to Top ↑

swap

Resizing a LVM swap volume

Another post mainly for myself, just so I know where to find the information quickly the next time I need it. If you have swap on a LVM volume, these commands can be used to resize it (in this case, increase by 100MB):

Back to Top ↑

fi mu

Using UTF-8 with fithesis

My faculty has it’s own thesis LaTex style, which makes it very easy to get a decent looking thesis out of LaTeX without too much effort. The problem is that the style requires you to use ISO-8859-2 in your document, which is something I can’t really live with. :) Here are instructions how to convert the style to UTF-8. I’m posting them here in hope that it will help some other student of Faculty of Informatics, Masaryk University in the future.

Back to Top ↑

fithesis

Using UTF-8 with fithesis

My faculty has it’s own thesis LaTex style, which makes it very easy to get a decent looking thesis out of LaTeX without too much effort. The problem is that the style requires you to use ISO-8859-2 in your document, which is something I can’t really live with. :) Here are instructions how to convert the style to UTF-8. I’m posting them here in hope that it will help some other student of Faculty of Informatics, Masaryk University in the future.

Back to Top ↑

latex

Using UTF-8 with fithesis

My faculty has it’s own thesis LaTex style, which makes it very easy to get a decent looking thesis out of LaTeX without too much effort. The problem is that the style requires you to use ISO-8859-2 in your document, which is something I can’t really live with. :) Here are instructions how to convert the style to UTF-8. I’m posting them here in hope that it will help some other student of Faculty of Informatics, Masaryk University in the future.

Back to Top ↑

tex

Using UTF-8 with fithesis

My faculty has it’s own thesis LaTex style, which makes it very easy to get a decent looking thesis out of LaTeX without too much effort. The problem is that the style requires you to use ISO-8859-2 in your document, which is something I can’t really live with. :) Here are instructions how to convert the style to UTF-8. I’m posting them here in hope that it will help some other student of Faculty of Informatics, Masaryk University in the future.

Back to Top ↑

ego

Technical book authors

To be honest, I don’t read technical books much. I prefer reading the official documentation for a product I need to work with, or use some other ways to get information about it. I always assumed people who write such books are experts though. There are many book authors on Stack Overflow, but today I encountered a particularly interesting situation with one of them.

Back to Top ↑

apache

Back to Top ↑

mod_rewrite

Back to Top ↑

web

Back to Top ↑

hg

Mercurial, part 1

I’ve been using Mercurial at work for two months now and the expectations I had about it didn’t change to anything better. I guess it looks cool for people who are used to SVN, or even CVS, and are not familiar with other DVCS. I must say that as a Bazaar user, I miss a lot of things. There are some that can be worked around, for something you just have to be extra careful and for something you are out of luck. I really don’t get how people use Mercurial for managing large projects.

Back to Top ↑

mercurial

Mercurial, part 1

I’ve been using Mercurial at work for two months now and the expectations I had about it didn’t change to anything better. I guess it looks cool for people who are used to SVN, or even CVS, and are not familiar with other DVCS. I must say that as a Bazaar user, I miss a lot of things. There are some that can be worked around, for something you just have to be extra careful and for something you are out of luck. I really don’t get how people use Mercurial for managing large projects.

Back to Top ↑

dbmodel

Database Modeller 0.3

Database Modeller 0.3 has been released. There isn’t as many changes as I wanted, but the main changes were unreleased for almost half a year. You can download the source code and Windows installer on the project page.

Back to Top ↑

php

Fun with timestamps

Some programming languages really encourage using UNIX timestamps for working with dates. PHP is a good example of such a language. Functions like date, strtotime, strftime are used all the time. Most people don’t realize that timestamps in general can’t really be used for calculations though. The problem is that most countries use daylight saving time, which means that two times a year the local timezone changes. This nicely breaks the assumption that every day has 24 hours. It doesn’t. Sometimes it has 23 or 25 hours.

Back to Top ↑

timezone

Fun with timestamps

Some programming languages really encourage using UNIX timestamps for working with dates. PHP is a good example of such a language. Functions like date, strtotime, strftime are used all the time. Most people don’t realize that timestamps in general can’t really be used for calculations though. The problem is that most countries use daylight saving time, which means that two times a year the local timezone changes. This nicely breaks the assumption that every day has 24 hours. It doesn’t. Sometimes it has 23 or 25 hours.

Back to Top ↑

gource

Back to Top ↑

video

Back to Top ↑

tomboy

Tomboy’s “Start Here” note

I use Dropbox to synchronize my Tomboy notes. This works very well, but there is a problem when setting it up on a new computer. Tomboy has a special “Start Here” note, which is used mainly for organizing other notes. When I tell it to synchronize notes from the Dropbox directory and overwrite the existing default notes, it will do so, but it doesn’t change it’s “Start Here” note pointer. As as result, Tomboy is not aware that my new Start Here note is the one it should use. As far as I know, there is no way fix this using Tomboy itself. It can be done only using GConf. Here is an example how to do it from the command line:

Back to Top ↑

quod libet

Submit tags from Quod Libet to MusicBrainz

I wanted to write something like this for a long time, but for some reason never did it. MusicBrainz has support for folksonomy tagging since 2007, but the coverage of track tags is still not very good. I try to keep some tags in the “genre” tag in audio files, but even with one-time import tool, I’m sure I’d not remember to run this on new files. So the idea here is to submit these tags to MusicBrainz as I listen to the files in my music player (Quod Libet). It’s inspired by a Quod Libet plugin called LastFMTagger, which does something similar, but for Last.fm. I had some free time today, so I wrote a plugin that does one-way synchronization of tags from Quod Libet to MusicBrainz. You can install the plugin using the following commands:

Back to Top ↑

autotools

Cross-compiling with CMake and Autotools

[The last time]/2010/07/introducing-chromaprint/) I needed to build a Windows binary, I found it easier to cross-compile it from Linux than to setup a development environment on a freshly installed Windows machine. The problem is that even though it’s not hard, you need to remember some obscure options. Today I needed to build a new version of ISRCsubmit and I had to search for the recipe again. So, let’s document it somewhere I can find it in the future…

Back to Top ↑

emusic

Custom file associations on GNOME

It seems that there is no GUI method settings associations for custom files in GNOME. I’ve had this problem before with dbmodel before. It writes save its data in XML files that end with the extension “.dmf”. The problem is that GNOME’s file associations work with MIME types and by default GNOME doesn’t know anything about these silly .dmf files, it only sees XML files, so if I want to automatically open .dmf files with dbmodel, I can either set it for all XML files or for nothing. I eventually gave up on trying to do this, but since I started to use eMusic and switched to Chrome, it become much more annoying.

Back to Top ↑

libmusicbrainz

Back to Top ↑

chrome

Playing with IRCCloud…

Yesterday I got my invite to IRCCloud, which is a web-based IRC client, but unlike other similar clients, the IRC connection is on the server, so I stay connected even when I close my browser. The first thing I had trouble with, after switching from a customized IRSSI, was that all nicknames had the same color. I never realized how much I rely on nickname colors, but it seems that I’m too lazy to read the nicknames. I wanted to try writing some user scripts for Chrome and this seemed like a nice opportunity. I stole the coloring algorithm from MusicBrainz’ chat logs and wrote this little script, which automatically sets a different color for nicknames in IRCCloud:

Back to Top ↑

irc

Playing with IRCCloud…

Yesterday I got my invite to IRCCloud, which is a web-based IRC client, but unlike other similar clients, the IRC connection is on the server, so I stay connected even when I close my browser. The first thing I had trouble with, after switching from a customized IRSSI, was that all nicknames had the same color. I never realized how much I rely on nickname colors, but it seems that I’m too lazy to read the nicknames. I wanted to try writing some user scripts for Chrome and this seemed like a nice opportunity. I stole the coloring algorithm from MusicBrainz’ chat logs and wrote this little script, which automatically sets a different color for nicknames in IRCCloud:

Back to Top ↑

irccloud

Playing with IRCCloud…

Yesterday I got my invite to IRCCloud, which is a web-based IRC client, but unlike other similar clients, the IRC connection is on the server, so I stay connected even when I close my browser. The first thing I had trouble with, after switching from a customized IRSSI, was that all nicknames had the same color. I never realized how much I rely on nickname colors, but it seems that I’m too lazy to read the nicknames. I wanted to try writing some user scripts for Chrome and this seemed like a nice opportunity. I stole the coloring algorithm from MusicBrainz’ chat logs and wrote this little script, which automatically sets a different color for nicknames in IRCCloud:

Back to Top ↑

compression

Binary fingerprint compression

While working on the Acoustid web service, I had a hard time deciding how to send fingerprints to the server. The fingerprints are vectors of fairly large 32-bit numbers. Sending the numbers in binary (which would be ideal) is not easy, because almost all web standards expect textual data, if not plain ASCII. The usual trick is to base64-encode binary data, but that increases the size by 33 %, which wasn’t acceptable for me. So I came up with the idea to compress the data using a special-purpose algorithm and then base64-encode the compressed data, and ideally also compress the base64-encoded data using GZip. The double-compression might seem weird, but it allows me to use only standard web tools and the resulting size is still smaller than using binary encoding.

Back to Top ↑

fingerpriting

Binary fingerprint compression

While working on the Acoustid web service, I had a hard time deciding how to send fingerprints to the server. The fingerprints are vectors of fairly large 32-bit numbers. Sending the numbers in binary (which would be ideal) is not easy, because almost all web standards expect textual data, if not plain ASCII. The usual trick is to base64-encode binary data, but that increases the size by 33 %, which wasn’t acceptable for me. So I came up with the idea to compress the data using a special-purpose algorithm and then base64-encode the compressed data, and ideally also compress the base64-encoded data using GZip. The double-compression might seem weird, but it allows me to use only standard web tools and the resulting size is still smaller than using binary encoding.

Back to Top ↑

gstreamer

Chromaprint plug-in for GStreamer

It’s been a long time since I learned some new framework (or even wrote some real code), so I decided to write a GStreamer plug-in that will wrap libchromaprint and make it very easy to generate Chromaprint fingerprints in GStreamer applications. This was inspired by a similar plug-in that Milosz Derezynski wrote for MusicDNS/libofa (the plug-in is now integrated in the official GStreamer distribution). Using the code from gst-ofa and gst-template, it turned out to be pretty easy. After a couple of hours, I was able to run commands like this and get valid fingerprints:

Back to Top ↑

musicdns

Acoustid submission API extended to accept PUIDs

As strange as it might sound, the Acoustid submission API can now also accept PUIDs instead of MBIDs. I had the idea of using PUIDs to help bootstrap the Acoustid database for a long time, but I avoided implementing it, because I was afraid of bringing all the PUID↔MBID matching errors to the database. The topic came up yesterday and I realized that with having the audio fingerprints, MBIDs and MusicBrainz metadata in the same database, I can pretty easily remove any suspicious matches. So I’ve made two changes to the submission API that should make importing of untagged audio files easier:

Back to Top ↑

puid

Acoustid submission API extended to accept PUIDs

As strange as it might sound, the Acoustid submission API can now also accept PUIDs instead of MBIDs. I had the idea of using PUIDs to help bootstrap the Acoustid database for a long time, but I avoided implementing it, because I was afraid of bringing all the PUID↔MBID matching errors to the database. The topic came up yesterday and I realized that with having the audio fingerprints, MBIDs and MusicBrainz metadata in the same database, I can pretty easily remove any suspicious matches. So I’ve made two changes to the submission API that should make importing of untagged audio files easier:

Back to Top ↑

ngs

Easier MusicBrainz NGS database setup

Some time ago I wrote a couple of tools that help me set up and update a mirror of the MusicBrainz database on the Acoustid server. It turned out to be work really well. Recently I’ve seen a few people struggling with setting up the NGS database using the original server codebase. The official route assumes you are going to run a MB server instance, which makes things a little bit more complicated than it has to be. You have to install a number Perl modules, you have to compile the MusicBrainz-specific PostgreSQL extensions, even though you most likely don’t need them, you are forced to setup a musicbrainz_db_raw database that you are definitely not going to use, because there is no data in it, etc.

Back to Top ↑

msvc

Back to Top ↑

zlib

Back to Top ↑

fail2ban

Making Fail2ban with IPFW firewall on FreeBSD work

The internet is a nasty place, everybody is trying to hack into your servers if they are publicly accessible. Even though I always disable password authentication, so there is very little chance somebody could “guess” my private RSA key, I don’t like /var/log/auth.log being spammed. Fail2ban is a nice solution to that I use on Linux with iptables, but it was not working for me on FreeBSD with IPFW.

Back to Top ↑

firewall

Making Fail2ban with IPFW firewall on FreeBSD work

The internet is a nasty place, everybody is trying to hack into your servers if they are publicly accessible. Even though I always disable password authentication, so there is very little chance somebody could “guess” my private RSA key, I don’t like /var/log/auth.log being spammed. Fail2ban is a nice solution to that I use on Linux with iptables, but it was not working for me on FreeBSD with IPFW.

Back to Top ↑

freebsd

Making Fail2ban with IPFW firewall on FreeBSD work

The internet is a nasty place, everybody is trying to hack into your servers if they are publicly accessible. Even though I always disable password authentication, so there is very little chance somebody could “guess” my private RSA key, I don’t like /var/log/auth.log being spammed. Fail2ban is a nice solution to that I use on Linux with iptables, but it was not working for me on FreeBSD with IPFW.

Back to Top ↑

ipfw

Making Fail2ban with IPFW firewall on FreeBSD work

The internet is a nasty place, everybody is trying to hack into your servers if they are publicly accessible. Even though I always disable password authentication, so there is very little chance somebody could “guess” my private RSA key, I don’t like /var/log/auth.log being spammed. Fail2ban is a nice solution to that I use on Linux with iptables, but it was not working for me on FreeBSD with IPFW.

Back to Top ↑

launchpad

Back to Top ↑

userscript

Back to Top ↑

architecture

Back to Top ↑

server

New AcoustID server release

I’ve just updated the AcoustID servers with the latest version of the code. There is a couple of changes on both the website and the API.

Back to Top ↑

wordpress

Blog moved to Jekyll

Just finished moving this blog from WordPress to static files generated using Jekyll, with Disqus for comments. Please let me know if you spot a broken link or some other problem.

Back to Top ↑

jekyll

Blog moved to Jekyll

Just finished moving this blog from WordPress to static files generated using Jekyll, with Disqus for comments. Please let me know if you spot a broken link or some other problem.

Back to Top ↑

sqlalchemy

Extending the SQLAlchemy SQL expression language

The SQL expression language from SQLAlchemy is already very flexible and allows you to build almost any standard SQL query, but sometimes you just need to use a SQL extension that isn’t supported by SQLAlchemy.

Back to Top ↑

testing

Twisted Trial and Jenkins

It’s not completely obvious how to configure a Twisted-based job that uses Trial for running tests in Jenkins, so hopefully this post will save somebody a little time in the future.

Back to Top ↑

ci

Twisted Trial and Jenkins

It’s not completely obvious how to configure a Twisted-based job that uses Trial for running tests in Jenkins, so hopefully this post will save somebody a little time in the future.

Back to Top ↑

solr

Alternative MusicBrainz search server

If you are working with a local MusicBrainz database and want to search in it, there aren’t that many choices. You can use the internal PostgreSQL full-text search or you can use the official MusicBrainz search server.

Back to Top ↑

lucene

Alternative MusicBrainz search server

If you are working with a local MusicBrainz database and want to search in it, there aren’t that many choices. You can use the internal PostgreSQL full-text search or you can use the official MusicBrainz search server.

Back to Top ↑

mbslave

Alternative MusicBrainz search server

If you are working with a local MusicBrainz database and want to search in it, there aren’t that many choices. You can use the internal PostgreSQL full-text search or you can use the official MusicBrainz search server.

Back to Top ↑

bitbucket

AcoustID code moved to Bitbucket

I was not very happy when GitHub announced that it discontinues project downloads. I was using GitHub to host compiled packages for Chromaprint and the AcoustID fingerprinter, as well as release tarballs for all AcoustID projects, so I had to start looking for alternatives.

Back to Top ↑

atlassian

Back to Top ↑

stash

Back to Top ↑

building

Daily Picard builds for Windows

Building the Windows installer of MusicBrainz Picard has always been problematic. I never had the process automated, it always involved a lot of manual steps which I could never remember. And because Picard releases do not happen very often, it was not very easy for people to test with the latest version on Windows (which usually included a number of fixes.

Back to Top ↑

templates

Closure Templates (Soy) for Python

For the past two weeks I’ve been adding a Python backend to Google’s Closure Templates. The work is now almost finished, so I’m happy to release a preview version of the Soy-to-Python compiler with a runtime Python library (closure-templates-for-python) and a Flask extension (Flask-Soy), to make it possible to work with Soy templates from Python.

Back to Top ↑

soy

Closure Templates (Soy) for Python

For the past two weeks I’ve been adding a Python backend to Google’s Closure Templates. The work is now almost finished, so I’m happy to release a preview version of the Soy-to-Python compiler with a runtime Python library (closure-templates-for-python) and a Flask extension (Flask-Soy), to make it possible to work with Soy templates from Python.

Back to Top ↑

closure

Closure Templates (Soy) for Python

For the past two weeks I’ve been adding a Python backend to Google’s Closure Templates. The work is now almost finished, so I’m happy to release a preview version of the Soy-to-Python compiler with a runtime Python library (closure-templates-for-python) and a Flask extension (Flask-Soy), to make it possible to work with Soy templates from Python.

Back to Top ↑

interview

Job interviews

I have been looking for a new position for a few weeks now. For the first time in my life, I’m trying to be more selective about what I do, so I went through a couple of interviews. I have come to realization that I’m unlikely to ever work on a good position for a larger company, that actually has some “hiring process”. The reason for that is that I’m just not built for job interviews. At all.

Back to Top ↑

tools

Using Raspberry Pi as an Arduino (AVR) programmer

I bought a cheap Arduino nano clone from eBay and after I plugging it in via USB, I was getting only errors when trying to upload some code. I realized it came without the bootloader installed. And I didn’t have a normal AVR ISP programmer to program the flash memory on the microcontroller.

Back to Top ↑

electronics

Using Raspberry Pi as an Arduino (AVR) programmer

I bought a cheap Arduino nano clone from eBay and after I plugging it in via USB, I was getting only errors when trying to upload some code. I realized it came without the bootloader installed. And I didn’t have a normal AVR ISP programmer to program the flash memory on the microcontroller.

Back to Top ↑

rpi

Using Raspberry Pi as an Arduino (AVR) programmer

I bought a cheap Arduino nano clone from eBay and after I plugging it in via USB, I was getting only errors when trying to upload some code. I realized it came without the bootloader installed. And I didn’t have a normal AVR ISP programmer to program the flash memory on the microcontroller.

Back to Top ↑

arduino

Using Raspberry Pi as an Arduino (AVR) programmer

I bought a cheap Arduino nano clone from eBay and after I plugging it in via USB, I was getting only errors when trying to upload some code. I realized it came without the bootloader installed. And I didn’t have a normal AVR ISP programmer to program the flash memory on the microcontroller.

Back to Top ↑

phoenix

Phoenix database adapter for Python

This is a small project I have been working on for a few weeks now. Mainly to get familiar with the Phoenix database, but also to just try something different from what I do at work or my existing open source projects.

Back to Top ↑

hbase

Phoenix database adapter for Python

This is a small project I have been working on for a few weeks now. Mainly to get familiar with the Phoenix database, but also to just try something different from what I do at work or my existing open source projects.

Back to Top ↑

letsencrypt

Let’s Encrypt and Nginx

I’m late to the game, but I finally gave Let’s Encrypt a try and I love it. The biggest advantage is the fact that SSL certificates can be completely automated. No more remembering how to renew certificates once a year.

Back to Top ↑

nginx

Let’s Encrypt and Nginx

I’m late to the game, but I finally gave Let’s Encrypt a try and I love it. The biggest advantage is the fact that SSL certificates can be completely automated. No more remembering how to renew certificates once a year.

Back to Top ↑

mbdata

mbdata 2016.07.17 released

I have released a new version of mbdata. It’s a small Python package for working with the MusicBrainz database using SQLAlchemy.

Back to Top ↑

msgpack

Msgpack serialization library for Zig

I’ve been playing with Zig over the last few weeks. The language had been on my radar for a long time, since it was originally developed for writing audio software, but I never paid too much attention to it. It seems that it’s becoming more popular, so I’ve decided to learn it and picked a small task of rewriting the AcoustID fingerprint index server in it. That is still in progress, but there is one side product that is almost ready, a library for handling msgpack serialization.

Back to Top ↑

ai

My AI helpers, CodeRabbit and SourceGraph Cody

I’ve been an early adopter of AI coding tools. I’ve been using GitHub Copilot from the technical preview stages in 2021. It was mind-blowing to me. The interface was pretty minimal compared to what we have now, but even at the stage, it was revolutionizing the way I work. I’ve dreamed for a long time about programming without having to actually write all the code, and it was starting to become a reality. All in all, I was pretty happy with it.

Back to Top ↑