beaTunes News

Wednesday, November 11, 2015

beaTunes 4.5.6

beaTunes4 logo

Another maintenance update. Fixed some minor indexing/display problems and a potential UI freeze.

As always, you can download the update from the download section of the website.

Most important changes in 4.5.6

  • Fixed wrong song selection in inspection when sorted.
  • Fixed partial artwork display in some sorted tables.
  • Fixed UI freeze after many Get Info edits.
  • Improved cross-platform playlist import.
  • Updated to Jipes 0.9.11.
  • Updated to JRuby
  • Updated to Groovy 2.4.5.

Labels: , ,

Wednesday, November 4, 2015

Splitting Stems with Java, FFmpeg, and FFSampledSP

Just a short note regarding the FFSampledSP library: Version 0.9.12 now provides an API for splitting Stem files into their parts. For a simple code sample, check out this page.

To split Stems from the command line, please take a look at my post from September 2015.

Labels: ,

Tuesday, October 20, 2015

beaTunes 4.5.5

beaTunes4 logo

Another maintenance update. Most interesting in this one is probably a fix for fingerprint-based metadata lookup.

As always, you can download the update from the download section of the website.

Most important changes in 4.5.5

  • Fixed null when writing key string in front of empty comment.
  • Fixed sort order toggle in match table when starting playback.
  • Fixed issue in fingerprint-based lookup.
  • Added $RECYCLE.BIN (all uppercase) to list of folders to ignore.

Labels: ,

Friday, October 2, 2015

You will want this update

beaTunes4 logo

Thanks to user feedback, I was able to discover and fix a nasty memory leak (Thanks, Willi!). So, if you had any kind of memory problem when using beaTunes, you will definitely want to update.

As always, you can download the update from the download section of the website.

Most important changes in 4.5.4

  • Fixed a memory leak.
  • Fixed lookup of songs with no album.
  • Fixed table order after BPM edit in sorted column.


Friday, September 25, 2015

This Open Key thing is great, but can I have parentheses, please?

beaTunes 4 introduced the capability to easily copy key values to the comment field during analysis. Pretty handy, as it allows easy access to key values from applications that don't really support keys (e.g. iTunes). Recently, I was told, that this works really well, but it would be even better to have parentheses around the Open Key code to better distinguish 2d from 12d when searching.

Thanks to the plugin API, there was a super simple solution to this: Just write a custom Key Text Renderer. The two needed classes, Key and KeyTextRenderer, are documented here and here.

And this is what the Groovy code looks like:

import com.tagtraum.audiokern.key.Key
import com.tagtraum.beatunes.KeyTextRenderer

class BracedOpenKey implements KeyTextRenderer {

     * Create a textual representation for a Key object.
     * @param key key
     * @return textual representation
    def String toKeyString(Key key) {
        String openKeyCode = key.getOpenKeyCode()
        // create the final string
        return "($openKeyCode)"    //  <- this is where we add the parentheses!

     * Create a tooltip representation for a key object.
     * This may also include html-tags.
     * @param key key
     * @return tooltip representation
    def String toToolTip(Key key) {

     * Short name of this renderer. To be used in the user interface.
     * @return name
    def String getName() {
        "Braced OpenKey"


To install, just save it in a file called BracedOpenKey.groovy and place it in the plugins folder. Upon restart, it will show up in the display format preferences and the export-as-comment option (see screenshot above).

Labels: , ,

Wednesday, September 23, 2015

Resetting iTunes Album Ratings

With the introduction of iTunes 12.2 a few months back, quite a few things changed for users and software vendors alike. One of the things that didn't come to my attention until recently is an oddity having to do with album ratings. It seems that hardly anyone really uses them, but if you have rated a couple of songs, iTunes displays an average of those ratings as the album rating. To signal that the values are computed rather than entered, they appear as gray stars as opposed to solid black stars. What happened when iTunes 12.2 was introduced is, that apparently some albums got ratings—nobody really knows where from. This resulted in all the unrated songs also showing ratings—gray ones, as they are computed, not entered. Obviously, everybody using smart playlists based on song ratings suffered.

Quite a bit.

A simple solution to the problem is to reset all album ratings to zero manually. Not very fun. When asked how to best solve the issue, I immediately figured that a library batch action can do the job. Library batch actions are little beaTunes plugins (often beaTlets), that do the same thing for all items in your beaTunes/iTunes library and can easily be scripted in Groovy/Jython/JRuby. So a library batch action for this particular problem really only needs to reset the album rating to 0 for all songs with an album rating other than 0.

Here's the Groovy code (download):

import javax.swing.Action
import java.awt.*
import org.slf4j.LoggerFactory
import com.tagtraum.beatunes.action.standard.LibraryBatchAction
import com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
import com.tagtraum.beatunes.MessageDialog
import javax.swing.JOptionPane
import com.tagtraum.audiokern.AudioSong

// An action that allows to reset all album ratings.
// The corresponding menu item can be found in the 'Tools' menu.
class ResetAlbumRatings extends LibraryBatchAction {

    // Inner class that implements the
    // com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
    // interface. Its process method is called for each song.
    class Resetter implements EachSongProcessor {

        static log = LoggerFactory.getLogger("ResetAlbumRatings.groovy")
        String file

        // Called once, before processing starts.
        def void startProcessing(int count) {
   "We are expecting to embed ratings for ${count} songs."

        // Called for each song.
        def void process(AudioSong song, int index) {
            int rating = song.getAlbumRating()
            boolean computed = song.isAlbumRatingComputed() // added as of 11/5/2015
            if (rating > 0 && computed) {                   // && computed 
                song.setAlbumRating(1)                      // set to 1 instead of 0
      "Reset album rating for " + song)
            } else {
      "No rating set in " + song)

        // Called once all songs were processed.
        def void finishProcessing() {
            new MessageDialog(getApplication().getMainWindow(),

        // Message to be shown in progress dialog.
        def String getProgressDialogMessage(AudioSong song) {
            "Resetting album rating of ${song.getName()}"

        // Title for progress dialog.
        def String getProgressDialogTitle() {
            "Resetting album ratings ..."

    // Unique id
    def String getId() {

    // Is called by beaTunes as part of the lifecycle after instantiation.
    // At this point all other plugins are instantiated and registered.
    // We use this to set the menu item's (i.e. action's) name.
    def void init() {
        putValue(Action.NAME, "Reset Album Ratings")

    // We need to ask the user, whether he really wants to do this.
    // How we ask is defined here.
    def String getConfirmationMessage() {
        "Do you really want to the album ratings of all your files?"

    // Factory method that creates the processor for each song.
    def EachSongProcessor createEachSongProcessor() {
        new Resetter()

You can install this like any other plugin—just make sure the code is in a file called ResetAlbumRatings.groovy (the file name must be the same as the main class name). To reset all album ratings in your library, restart beaTunes after the plugin installation, and open the Tools menu. There should now be a new item called Reset Album Ratings (see init() in the code). When running this action, please be careful: You won't get to say "yes" or "no" for each individual album. That's why it's called a batch action. Also, changes cannot be undone.

Library batch actions are a great way to fix something in your entire library. And it's not rocket science. Basic understanding of Groovy (or some other popular scripting language) is typically all you need.

Update 11/5/2015

I have changed the script slightly, as a response to... well... it not working. Please re-install the script and make sure it contains the line boolean computed = song.isAlbumRatingComputed(). Also, the script may still be applying changes in the background, even after it reports that it's done. Give it a couple of minutes (or check the beaTunes logs for activity). Thanks for your feedback!

Labels: , ,

Tuesday, September 22, 2015

Introducing Quick-Search

beaTunes4 logo

With increasing collection sizes, navigating the library becomes more and more difficult. Of course you can filter and search, but quickly going to an album or artist with just a couple of keystrokes is probably the easiest way to navigate. Starting with beaTunes 4.5.3, this is now possible.

Here's how:

For quick-search to work, you need to sort your library by one of the textual columns, e.g. Artist or Album. Make sure the table has the keyboard focus and then start typing the first couple of letters of what you are searching for. In an overlay, beaTunes will show those letters and—once you stop typing—scroll to the next matching row.

As mentioned above, this works for pretty much all textual fields and one additional column: BPM. So when the table is sorted by BPM, you can simply type 100 and beaTunes will scroll to the first song with 100 beats per minute.

There are a couple of other improvements and fixes. Details can be found below. As always, you can download the update from the download section of the website.

Most important changes in 4.5.3

  • Fixed exception after clearing ignored issues.
  • Fixed HiDPI drag and drop images.
  • Fixed error in bpm range coercion arithmetic.
  • Fixed exclusion of audiobooks/iTunesU/home videos from analysis.
  • Added current heap memory use info to About dialog.
  • Added quick-search popup for sorted playlists.
  • Added visual indicator for computed ratings.
  • Improved sync of folder-based-library.
  • Improved built-in Help.
  • Improved AppleScript/COM error reporting.
  • Improved handling of digital booklets.
  • Improved different album artist inspection.

Labels: ,