SongKong Jaikoz

SongKong and Jaikoz Music Tagger Community Forum

Featured and "co-artist" handling

Hi (Paul, mostly),
Really, this is about the “co-artist” situation, but I wasn’t sure the title would make much sense without mentioning ‘featured’ artists to help build context.

I’ve noticed in a couple albums (most recently this one by Sia that even though I’ve selected:
When tracks contains featured artists : Only use main artist in the artist field and add others to the title field
The ‘other’ artist still shows up in the artist field. In this case, I’m thinking of Kylie as the ‘other’ artist. I’m looking at track 3, “Dance Alone”, which Sia and Kylie Minogue are apparently sharing performance credit for (depending which release, but in my case, “yes”).

I’m thinking this is probably correct/desired behavior, because it appears they’re being credited as co-performing the song, vs one of them being ‘featured’, as is happening on Track 2, “Immortal Queen” ft. Chaka Khan.

However, I don’t like it :slight_smile:

I use a variety of UIs to listen to music, sometimes including relatively dumb ones that aren’t really feasible to update, and even if updated, may not gain much brains. I’m talking about players built into not-so-fresh cars as the really egregious ones. And of course the ridiculous oddball that Sony produced which we’ve recently discussed.

I typically like to listen to music by album. In a case like this, I’ll select Sia, and play the music for the album (Reasonable Woman), and one or more of my dumb players will end up skipping the song co-performed by Kylie. Also, I’ll have this ‘stupid’ entry on my player’s Artist listing that says “Sia & Kylie Minogue” which lists the album, and just that one single song.

It’s ‘correct’, but annoying, and counter to the way I like listening to music. In the olden days I’d have popped a record or tape or CD in, and listened to the album, which I’d consider a Sia album. It would be sorted on my shelf under Sia, and would of course play all the tracks in order.

Sometimes I use shuffle/random, but not usually. When I do, it doesn’t matter.

To avoid this nuisance, I’d prefer to ‘squash’ Kylie’s involvement from the Artist field. Since SongKong offers the “‘ft xxx’ in the title” feature, which I think is brilliant, I do that. I don’t find adding that info to the title at all offensive, helps remind me that Kylie is the other voice, and doesn’t make a mess of my playback experience.

Yeah, serious first world problem… :smiley:

Could I ask you to add another option in the UI to treat co-artists similarly to featured artists? (I guess giving first-listed credit, or maybe looking at the album artist value…) Not sure if it should be an option in the existing question, or a new question. I’ll let you sort that detail, seeing as it’s your app and you’ve surely given this more thought than I have already. I think a separate question my make more sense, though. I can’t think of a great way to present it that isn’t too cumbersome.

Dance Alone (ft Kylie Minogue) is ok, (though inaccurate in this case, so, no)
Dance Alone (co-performed with Kylie Minogue) seems a bit too wordy.
Dance Alone (with Kylie Minogue) sounds too much like it’s a ‘featuring’ relationship, minimizing her involvement. But maybe that’s ok, since it’s not default behavior, and the tagger (me) is choosing to do it…

Of course, if this is already feasible, and I’m missing it, please let me know.

The ‘data purist’ in me kinda doesn’t like the idea of ‘squashing’ this info out, but I more greatly dislike how the treatment of that info by lousy players screws up the album playback experience. N.B., I do realize that in most (all?) cases I could work around the problem by selecting the album WITHOUT picking the artist first, but that’s not really the way my brain works when I’m deciding what I want to listen to.

For now, I address this by using Jaikoz to ‘fix’ the offending song when I notice it. So, it’s not urgent or anything. It doesn’t come up that often. I do generally notice it when I suck the song into my own playlist management app and go to add the song to a playlist (which is used to keep my usb sticks / music players in sync with what I want on them.)

Thanks for reading.

Hi, okay I understand what you are saying apart from the bit about picking album without artist, don’t you mean allbum artist instead of (track) artist and in this case the album artist is consistently Sia so would be no issue and whole album displayed ?

Sorry, it was a bit rambly…

A lot of players (I’m talking about players in cars, handhelds, etc. NOT iTunes, Plex, etc, which tend to be much more flexible) allow you to drill-down into your selection either by Artist, Album, or Track. That seems to be the lowest common denominator.
Some support more options of course (Album Artist, E.G.)

Picking an Album without first picking an Artist is problematic when you have a lot of music at your finger tips, but can be helpful if you want to play a Soundtrack, or some other collection which would reasonably have “Various Artists” as the Album Artist.

Since my cars (and handheld players) don’t support Album Artist as a selection criteria, my next best option after Artist is Album.

Hope that clears that up.

Thanks

Okay got it, will consider further.

Hi, I thought about this a bit more and Im wondering if the issue actually is that the co-artist can be added to track artist or is just that track artist is not consistent for the album. What I mean by this is in your scenerio you are having to use track artist as the album artist, in most cases they will be the same but in some cases for some tracks some of the track artists may differ from album artist because of co-artists issue that you describe. Now if there is a co-artist credit and the non album artist is first credited then if I apply your fix that track artist will then be different to album artist so even though the track artist field has just one value it wil be different to album artist and hence have same problem.

And there could also be some other circumstances where track artist is not the same for all tracks that would not be fixed by changing the handling of the co-artists.

Whereas if you could just do if(AlbumArtist!=Various Artists" set Track Artist = Album Artist) that would fix the issue for your situation. I already have these two issues that would allow you to do that.

https://jthink.atlassian.net/jira/software/c/projects/SONGKONG/issues/SONGKONG-2625
https://jthink.atlassian.net/jira/software/c/projects/SONGKONG/issues/SONGKONG-2616

I think this would maybe a a better solution for you?

Hi Paul,

I’ve spent several hours thinking about this now, writing, rewriting, reading and exploring (rediscovering!) the existing capabilities of Jaikoz and SongKong, and, I’m getting tired or trying to make this post really coherent and brief. :slight_smile:

That said, the TLDR is:
I’m not sure… I think it may be a better feature for the ‘Scripter’ mentioned in https://jthink.atlassian.net/jira/software/c/projects/SONGKONG/issues/SONGKONG-2625?jql=project%20%3D%20"SONGKONG"%20ORDER%20BY%20created%20DESC

I think the find-replace metaphor may not be ideal because I’d need to update TWO different fields (title and artist) based on relationship of two fields (artist and albumartist)


Here’s my more detailed/roundabout way of coming to that conclusion.

I had forgotten about the Auto Edit feature’s existence, having never used it.

I see the point you’re making in the first paragraph. And yes, you’re right; the real problem is that the [Track] Artist field is inconsistent for the album. This is only a problem when dealing with a UI that doesn’t know to pay attention to Album Artist. Actually, I think the subtleties regarding how a UI should treat Album Artist vs Artist in various scenarios probably warrants a small essay, so I’ll leave it at that, but acknowledge it’s really not quite that simple.

For purposes of this discussion, to work around brain dead UIs, the search and replace operation you’re suggesting would fix that part of the problem.

But it doesn’t update the title to include the co-artist info. (Or ‘other’ artist.). I would like to preserve their involvement in some way, even though that is of secondary concern.

I’m not sure the find/replace metaphor would work for this unless you could build up complex operations:

if (AlbumArtist != "Various Artists") {
  set title = title + " ({ListOfContributors(AlbumArtist, TrackArtists)})"
  set TrackArtist = AlbumArtist
}

This snippet assumes that there is a concept of a multi-valued “TrackArtists” (seems a fair guess) which includes all artists who worked on the track, including an indication of whether they were ‘featured’ or should receive “co-artist” billing. The “ListOfContributors” function would be responsible for figuring that all out. It could be defined by the user, or built-in.

So, my first thought is that this example may be more than you had in mind for the find/replace macro capability. (Actually, I think “find/replace” stops being a good name for it at this point. It’s just a script. (Note from Future Jason: It was shortly after I wrote this last bit, as part of a ‘go back and re-write that part’ that I went back and re-read your JIRAs and noticed you had made mention of a possible “Scripter”) It basically requires what amounts to a domain specific language. But I guess you kind of have that already in the file/folder renaming masks.

Assuming “artists” contains the required data, if you built this, I think that would satisfy my desire.

A few thoughts on that, however.

  1. I’d prefer not to have to run a separate find/replace operation after I’ve done fix songs (I may not even know that it’s required until later)
  2. If it was run as a separate operation, I be concerned about making sure the operation was defined in a way that makes it idempotent so that accidental multiple runs wouldn’t ‘corrupt’ the data. (imagine I have to run it on one album, and then later I run it for the artist, or my whole collection, etc.)
  3. If the operations could be chained to an existing Fix Songs or Monitor Watch Folder profile, that might help address both of the above concerns.

Is that what you had in mind? Or did I just make it way more complicated?


So, that’s where I was when I saw that you had mentioned a Scripter which I guess is on the roadmap, and I thought, crap, I don’t want to re-write all of this AGAIN :).
I think the Scripter (if it resembles what I described above) could do this. Find and replace? Meh, that might be hard (thinking about how that would apply to the title field).
I don’t know for sure that “Artists” is structured the way I’m assuming it is, but I’m guessing that whatever info you used to do the current “featuring” process could be made available, and that a user could write code that could tell the difference between a co-artist and a featured artist.
It would be good if Scripts could be added to Fix Songs and Monitor Watch Folder as post-operations (maybe pre-operations, too? Not sure. I don’t have a use case for that at this moment, and can’t really imagine what the point would be, before the data was Fixed. I guess that depends on what operations are in scope for Scripting.)

The checkbox with multiple options seems a lot simpler, but if you see another solution available that’s more general, flexible, and powerful, but needs your focus to deliver, I get it. I’m not sure how many users would be into that kind of tool. Maybe a lot. (I just realized recently that the community of people who own a swimming pool and maintain it themselves has a much higher proportion of nerds than the general public - maybe this is another such population!)

Okay I forgot about the title thing, yes you are right if you want to do that then find and replace wouldn’t work, and even it did would gave issue if rerun if using title += title idea.

Scripter would be powerful enough for this but may still have the rerun issue.

Your original solution would work (in most cases). But I’m not that keen to add an option that essentially adds wrong data just to compensate for a bad car ui that only you may use.

Will muse further.

Okay I am making good progress with Scripter task, (it works I just need to build web UI and a few other things). Scripter task will not only let you set metadata fields to combinations of other metadata fields, if the song is linked to a MusicBrainz or Discogs album then you can use the native values from the matched mb or discogs release. So I think it will possible to create a script that can be rerun on the same files more than once and get same result - https://jthink.atlassian.net/browse/SONGKONG-2639

Also note, that although this means you currently will have to run Fix Songs and Scripter this gives the best flexibility, and in future will be able to chain together tasks.

Very Exciting!

Few thoughts I’ve had (some a while back, some just now).

So I think it will possible to create a script that can be rerun on the same fies more than once and get same result

It occurred to me later after writing the bit about idempotence that that is really the script writer’s responsibility - and as long as I run it as part of an Fix Songs operation (an ‘after’ step) I can assume that while the update may not be idempotent, the total operation would be (because the Fix would reinitialize the title.).

However, if there are other authoritative versions of that same info (MB, Discogs) - that’s even better - that can be treated as a read only source.

Out of curiosity, how are those stored? In the file? Or in the SK database? For that matter, are those (and other similar fields) already documented somewhere?

Two other thoughts, brought about by the Jiras you linked:

  • For https://jthink.atlassian.net/browse/SONGKONG-2627, I don’t know what you’re thinking, but one approach could be to create a ‘macro’ feature that allows you to orchestrate other operations - that way the other operations don’t have to grow any extra brains about that concept - keeps it modular. Not sure that’s the best way, just popped in my head.
  • For https://jthink.atlassian.net/browse/SONGKONG-2639, I note that you refer to it as a ‘task’. I was assuming the Scripter would allow you(me) to write arbitrary JavaScript similar to what I think I’ve seen in the other areas, which would just allow you to read/write values - is that not what you had in mind? Or is it what you meant, but you intend to write a function so that I don’t have to do it myself?

Are you thinking the Scripter will be able to operate beyond the context of songs? I realize I don’t know what your vision for that is.

Have a good weekend, and thanks for the update
Jason

The mb, discogs values are taken from the MusicBrainz or Discogs release/Track just like when we run Fix Songs.

If you consider the rename files mask part of the Rename Files script that lets you write javascript to modify the filename.

Scripter simply extends this so that can modify multiple metdata fields to other metadata fields using javascript.

We will provide some useful scripts similar to how we provide some rename masks and you can use these, combine these or write your own scripts from scratch. But the end result of any script is simply that you can use it to modify metadata fields, not anything else.

And I have extended both Scripter and Rename Files so if your song is matched to MusicBrainz or Discogs then you can also use certain info directly from these rather from your metdata fields i.e MusicBrainz release title rather than the album metadata field. This is a new concept, so not currently part of SongKong.

Your macro idea is essentially how I’m going to do it, the chained tasks are not aware they are part of a larger workflow.

Cool - makes sense, and sounds awesome. :slight_smile:

The mb, discogs values are taken from the MusicBrainz or Discogs release/Track just like when we run Fix Songs.

I understand that, I think. What I meant was… When we run one of these scripts, and it refers to (for example) “MusicBrainz release title”, will it make an API call every time? Or will it pull it from the file? Or a local cached value in a DB? Etc.
And if that value doesn’t exist already (or, assuming an API call is to be made), it hasn’t been matched to MB yet, would it just use an empty string?

We have a cache that we add MusicBrainz releases to so usually just have to get from api once. If no match yes would be empty string.

So I have written this for Scripter, seems to work but might need finessing.

   if(albumartist!='Various Artists')
{
   artist=albumartist;
   var ft='';

   for (var index = 0; index < artists_index.length; index++) 
   {
      if(!artist.contains(artists_index[index]))
      {
         ft+=artists_index[index] + '; ';
      }
   } 
   if(ft.length>0)
   {
      ft=ft.substring(0, ft.length-2);
      if(mb_track_title.length()>0)
      {
         title=mb_track_title +' (Ft.' + ft +')';
     }
     else if(discogs_title.length()>0)
      {
         title=discogs_title +' (Ft.' + ft +')';
     }
   }

So for any song with albumartist not credited to ‘Various Artists’ the (track) artist is set to albumartist . If song has been matched then we should have also an artists field containing each track artist as a separate value. So we loop around these and if we cannot find the artist in the new artist field then we add the artist to a ft variable plus a '; ’ seperator. At the end of the looping if ft has a value and we have a MusicBrainz match we then set title to mb_track_title + value of ft variable. Because we are using mb_track_title we are always using the original value, alternatively if only Discogs match we use discogs_title If neither then we cannot modify the title so maybe cannot capture extrack artists but we can still ensure artist is now the same as albumartist.

That’s great!

That script looks like it would do the trick. I take it that the variable “artist_index” is a actually a list of the artists? (The name threw me off at first; I thought you’d made a typo.)

My other question: Is there a way to tell the difference between a “Featuring” and a “with”?

I’ll draw your attention back to the songs on the album I’d highlighted at the beginning of this.
Album release: https://musicbrainz.org/release/b2f15f37-aaea-4dd4-bf12-820da0999cd8
Track 2 (Immortal Queen; Sia feat. Chakha Khan): https://musicbrainz.org/recording/03502caf-336f-4f0a-a1cc-bf0b5bbd4394
Track 3 (Dance Alone Sia & Kylie Minogue): https://musicbrainz.org/recording/25278947-ab81-427e-b58d-1518e0492b67

I can’t tell from the MB UI how they distinguish, but I guess from the UI treatment (“feat.”" vs “and”/"&") that there is some difference in how it’s stored (or in other metadata).
Is that distinction available in the SK context?

It is artists_index. So the artists field stores the artists as a list of values whereas artist field stores as one value. When you access any metadata field with the scripting if it has multiple values then they are returned in the form artist1;artist2;artists…. But you can also access an array of values by adding _index to the end of the script field name as we have done.

Your second question confuses me. MusicBrainz actually returns an artist credit which consists of a list of artists and the join phrase between them, and within Fix Songs we use the join phrase to decide whether the artist is a featured artist or Co artist. But your request was to ignore this logic and move all artists apart from those matching the album artist(s) to the track title as if they were featured artists.

“artsits_index”, yes… That was my typo :slight_smile:

The _index bit makes sense, thanks for explaining that.

Sorry for the confusion - it wasn’t my intent to disregard the distinction between a featured artist and a co-artist; my intention was just to get that info out of the Artist field, and into the Title field.

As I wrote in the first post:

Dance Alone (ft Kylie Minogue) is ok, (though inaccurate in this case, so, no)
Dance Alone (co-performed with Kylie Minogue) seems a bit too wordy.
Dance Alone (with Kylie Minogue) sounds too much like it’s a ‘featuring’ relationship, minimizing her involvement. But maybe that’s ok, since it’s not default behavior, and the tagger (me) is choosing to do it…

I would prefer to preserve the distinction if I can.

If the data is available, I’d probably write something that would produce output options such as the following (assuming the data led to these outcomes):

  • Immortal Queen (ft. Chaka Khan)
  • Dance Alone (with Kylie Minogue)
  • Fake Song (with Kylie Minogue; ft. Chaka Khan)
  • Other Fake Song (with Kylie Minogue and Madonna; ft. Chaka Khan and Chris Martin)
  • SuperGroup Song (with Kylie Minogue, Jewel, and Madonna; ft. Chaka Khan, Kid Rock, and Chris Martin)

Getting really crazy there, but I think that would handle all cases that are possible - I’d probably opt for the serial comma even though it seems to be out of vogue, because it is more clear than omitting it (IMO) when faced with Artists like “Simon and Garfunkel”.

In one of the other posts above, I’d written:

This snippet assumes that there is a concept of a multi-valued “TrackArtists” (seems a fair guess) which includes all artists who worked on the track, including an indication of whether they were ‘featured’ or should receive “co-artist” billing. The “ListOfContributors” function would be responsible for figuring that all out. It could be defined by the user, or built-in.

So, all that said to say, yeah, I think this basically nails it. Where do I find the MusicBrainz artist credit field? is it already exposed as mb_artist_credits_index? And how is the join phrase presented? Is it embedded in the string containing the artist name? Or is it a separate value? (please, please, please let it be a separate value, like a 2d array, or another attribute, or something like that :smiley:)

I hope I’m not being a pain in the rear, here - not trying to be. I’m happy to write the JavaScript portion myself, too, if that’s any use. I just need to know where/how to find the data.

Are the fields available in the Scripter’s context documented anywhere yet? Or too soon?
Failing that, is there a mechanism by which you can log (to something - console? log file? etc) so that you can inspect the values found?

Is there a version of this I can play with, yet?

I just spent a few minutes digging into the MB API - I didn’t realize it was freely available. It looks like the way the joinphrase is handled may make my suggestion above non-trivial. It appears that each artist-credit gets a joinphrase that tells you how to connect to the next artist-credit rather than how the current artist should be connected to the entity (track, in this case).
https://musicbrainz.org/ws/2/release/b2f15f37-aaea-4dd4-bf12-820da0999cd8?inc=artist-credits+labels+discids+recordings&fmt=json

That offers some flexibility (they can add new joinphrases trivially) and it makes it easy to string them together like a sentence, but it makes it more difficult if you wanted to do things like, say, highlight featured artists in the UI with yellow, while highlighting primary and co-artists in green. It also explains why it has seemed somewhat random with regard to the choice between “&” and “and”.

Interesting.

TTFN

In my script im getting the track artists value from the artists field rather then the mb_artists, i.e using the artists field that was populated when the song was matched to MusicBrainz rather than just using the mb track artists directly. Now this is not neccessarily the same as the track artists linked to the track on MusicBrainz because affected by all these options:

  • When Tracks contain Featured Artists
  • Romanize non Latin Artist script artist names whenever possible
  • Use standard Artist name rather than name on cover
  • Use Recording Artist instead of Track Artist

And also some additional cleverness for classical albums that recognizes Track Artist and Recording Artist are intended for different things (composer/performers) on Classical and have to be treated specially.

Now we could use mb_tracks_artists instead but that would then mean we lose that logic, this maybe fine or you may need to code into the function. If you want to process the join phrases that is not stored in your songs fields seperately so you would have to use the mb variables. Please realize our mb variables are a different MB api to what you are looking at, only the original data is the same.

So my gut feeling is you are possibly making this too complex considering the problem you are trying to solve is playing whole albums on a limited car audio system. None of this is availble is yet, but it will be in the next release and then you then experiment yourself, hopefully be released within a couple of weeks.

I have extended script a little

if(albumartist!='' && albumartist!='Various Artists')
{
   artist=albumartist;
   var ft='';

   for (var index = 0; index < artists_index.length; index++) 
   {
      if(!artist.contains(artists_index[index]))
      {
         ft+=artists_index[index] + '; ';
      }
   } 
   if(ft.length>0)
   {
      ft=ft.substring(0, ft.length-2);
      if(mb_track_title.length()>0)
      {
         title=mb_track_title +' (Ft. ' + ft +')';
      }
      else if(discogs_title.length()>0)
      {
         title=discogs_title +' (Ft. ' + ft +')';
      }
   }

   artists=albumartists;
   artistsort=albumartistsort;
   artistssort=albumartistssort;
}

Script is now available as part of SongKong 11.0 Humbug released 11th October 2024

Sweet! I’ll be checking that out today!

Thanks