Proposed Genre Mapping Plugin

I’m considering developing a Picard plugin to allow mapping genre tags to standard values based on user-specified mapping criteria. Before I spend any time on it, I’m curious to know if anyone would find it useful to them. Personally, I try to avoid genres like the plague when it comes to tagging and organizing my music collection, but I know that it’s very important to others.

What I’m thinking of is to add a new scripting function $mapgenres() which would take a multi-value variable such as %genres% as an argument. The function would look up each item in the variable list to see if there is a match in the mapping list, and if found it would include the mapped item in the output. The function output would be a new multi-value variable.

For example, if %genres% contained an item “Prog Rock” and the user had mapped this to a standard replacement “Progressive Rock”, then the output would contain the replacement “Progressive Rock” rather than the original “Prog Rock”. If there was no match found in the mapping list, then the genre would be dropped from the output.

I envision the mapping file being a simple text file easily maintained by the user. There are a couple of ways that it could be formatted, such as:

Format 1

From1 => To1
From2 => To2
...

where each mapping pair appears on a separate line.

Format 2 (my personal favorite)

To1:
 - From1a
 - From1b
 - From1c
To2:
 - From2a
...

where each mapping group starts with the desired replacement, followed by a list of all the inputs that map to that target. This allows the user to more easily map multiple inputs to a single target output.

The output would use the case specified in the mapping list, but the input test comparison would be case-insensitive, and all duplicate outputs would be removed so that the resulting list would be unique.

The mapping file could either be specified as an argument to the function, or could default to a specific file genremap.txt in the default naming directory.

So what do you think? Is this something that anyone would find useful?

2 Likes

Considering this will probably be quite some work for you, I see one or two obstacles that might hinder it being enough useful/successful at this moment.

If a user retrieves the genres from MusicBrainz, the genres retrieved are (while limited) usually already in a decent format.
There are a couple I personally prefer differently, but a script can handle that.

If the user already has genres in his tags (perhaps retrieved elsewhere, Wikidata, Discogs, or manually entered etc.), and wants to update the file(s) using Picard, it is impossible to have Picard read the existing genre tags, retrieve genres from MusicBrainz, and then process those together.
(correct me if I am wrong?)
If that was possible, I think the plugin you are imagining/suggesting would be quite useful.

Ideally a genre plugin would additionally be able to retrieve genres from different sources in the same run, and process them together, including genres tags that are already in the file.

Note that I wrote this a bit impulsively as a first response.
I may have some facts wrong, and I may be wrong thinking such a plugin would not be very useful at this moment in time.
So take all this as some random thoughts on the matter in trying to give some input and possibly help in having a fruitful further discussion.

1 Like

MB genres are only ever going to be as useful as they are consistently applied.

The good news is that there is a restricted list of tags that MB considers to be genres, so we don’t see quite the pollution of genres that e.g. lastFM suffers from - and less of a need for code to clean them up. But if you want to use genres from other sources as @hiccup points out, then the clean up is much more difficult.

Plugins like this can help, but until genres are handled in a more curated (required and voted) and structured (consistent use of case, hierarchical, selected from dropdowns) fashion they will always be very hit and miss.

But, the whole purpose of plugins is to allow exactly this type of functionality to be delivered and tried. So please don’t let my negativity stop you. :slight_smile:

2 Likes

Yes! This would be most helpful. For this purpose I’ve been using a large set of $replacemulti() functions in a taggerscript, e.g., $replacemulti(%genre%,Rhythm And Blues,R&B). But something with a better layout and multi-to-one capability (so “Format 2”) with (I would highly recommend this:) a number of out-of-the-box definitions would be great!

I agree, insofar as MB itself is concerned. But one benefit of a plugin like what @rdswift is proposing is that it will help standardize one’s genre tags across different databases. (I currently use MB and Wikidata.)

The lastFM plus plugin essentially consisted of functionality to get genre data from lastFM and a second set of functionality - including an Options UI - to simplify and make it consistent.

IMO this second set of functionality would make an excellent start to a generic plugin (that would run after all other genre plugins had completed) to make sense of a messy set of genres.

Useful points.

In general, I think two sets of features would be helpful. (I don’t know if any existing plugin does this already.)

  1. Checking genre / style tags from multiple sources and consolidating them into more standardized names/spellings.
  2. Using the above data to rank the tags in terms of most common to least. This could also possibly be used to only list those tags that are present in at least two sources.

I quite like this idea of comparing sources for common genre entries - in principle at least because I suspect that there would be lots of minor spelling changes that would need to be handled.

“C&W” vs. “Country and Western” for example.

But if the various genre lists are cleaned up and standardised before comparing, then I guess it could work.

Well, I finally got around to doing something about this, and have created a plugin. It’s still in pre-release status, but I think it’s ready for general use (testing). If you decide to give this a try, I would appreciate any feedback (good or bad) so that I can make any required changes before submitting it for consideration for inclusion on the “official” Picard plugins page. Thanks.


Genre Mapper [Download]

Overview

This plugin provides the ability to standardize genres in the “genre” tag by matching the genres as found to a standard genre as defined in the genre replacement mapping configuration option. Once installed a settings page will be added to Picard’s options, which is where the plugin is configured.

This plugin is set to run at low priority so that any other plugins that might affect the list of genres are processed first.


Settings

The settings panel allows the user to provide a list of the original/replacement pairs used to modify the genres provided in the “genre” tag. Each pair must be entered on a separate line in the form:

[genre_match_test_string]=[replacement_genre]

Supported wildcards in the test string part of the mapping include ‘*’ and ‘?’ to match any number of characters and a single character respectively. Blank lines and lines beginning with an equals sign (=) will be ignored. If the replacement part of the pair is blank, any matching genres will be removed. Case-insensitive tests are used when matching. Replacements will be made in the order they are found in the list.

There is also a setting which allows the user to choose whether or not to apply the first matching pair only, or continue processing the remaining pairs with the updated genre. By default, all of the pairs are processed.


Examples

Example 1

Suppose that you want to combine all the different types of rock genres (e.g. Country Rock, Hard Rock, Progressive Rock, Punk Rock, Rock ‘n’ Roll) into a single “Rock” entry. This could be done using the following matching pairs configuration:

=============================
= Combine all "Rock" genres =
=============================
*rock*=Rock

Example 2

Similar to Example 1, except that you want to keep “Punk Rock” separate from “Rock”. This could be done by enabling the “Apply only the first matching replacement” option and using the following matching pairs configuration:

====================
= Keep "Punk Rock" =
====================
punk rock=Punk Rock

=============================
= Combine all "Rock" genres =
=============================
*rock*=Rock

This would cause a genre of “Punk Rock” to match the first test, keep the genre as “Punk Rock” and stop processing that genre entry. If the “Apply only the first matching replacement” option was not enabled, processing would continue and the next match would change the genre to “Rock”.

Example 3

Similar to Example 2, except that you want to keep processing rather than stop on the first match. This could be done by disabling the “Apply only the first matching replacement” option and using the following matching pairs configuration:

================================================
= Keep "Punk Rock" as temporary "Temp1" tag so =
= that it doesn't match any following lines    =
================================================
punk rock=Temp1

=============================
= Combine all "Rock" genres =
=============================
*rock*=Rock

===========================================
= Additional processing pairs as required =
===========================================

==============================================
= Change the "Temp1" tag back to "Punk Rock" =
==============================================
temp1=Punk Rock

This would cause a genre of “Punk Rock” to match the first test, changing the genre to “Temp1” (not matched in any of the following processing pairs) and continue processing. The final processing pair matches the “Temp1” genre set earlier and changes the genre back to “Punk Rock”.

5 Likes

This is amazing - thank you.

1 Like