[sound-juicer] Get composer metadata from musicbrainz relations



commit 10d6dba86ca2a31d28760dad9e69e2c3f8df1874
Author: Phillip Wood <phillip wood dunelm org uk>
Date:   Wed Mar 28 14:01:57 2012 +0100

    Get composer metadata from musicbrainz relations
    
    In Musicbrainz composers are related to works via composer relationships
    and works are in turn related to recordings via performance
    relationships. Use these to fill the composer metadata. This could
    easily be extended to arrangers and lyricists.
    
    Musicbrainz allows more than one relationship list to be associated with
    any given object, however libmusicbrainz 4.0.0 only supported retrieving
    one of them. This lead to problems getting the composer data for some
    albums. Thanks go Andy Hawkins, the libmusicbrainz maintainer for
    extending the API in version 4.0.1 to support retrieving all
    relationship lists for an object.
    
    Get track duration data from Mb4Track instead of Mb4Recording as the
    track data is more accurate. (During testing several albums had no
    duration data in their recording objects and some had incorrect data.)
    This is how we got the track duration when we used libmusicbrainz3 and
    it was reliable then.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661646

 libjuicer/sj-metadata-musicbrainz4.c |  125 +++++++++++++++++++++++++++++++---
 1 files changed, 115 insertions(+), 10 deletions(-)
---
diff --git a/libjuicer/sj-metadata-musicbrainz4.c b/libjuicer/sj-metadata-musicbrainz4.c
index 573ef64..e6b7485 100644
--- a/libjuicer/sj-metadata-musicbrainz4.c
+++ b/libjuicer/sj-metadata-musicbrainz4.c
@@ -229,6 +229,95 @@ fill_relations (Mb4RelationList relations, AlbumDetails *album)
 }
 
 static void
+fill_work_relations (Mb4Work work, TrackDetails *track)
+{
+  Mb4RelationListList relation_lists;
+  unsigned int j;
+
+  if (work == NULL)
+    return;
+
+  relation_lists = mb4_work_get_relationlistlist (work);
+  if (relation_lists == NULL)
+    return;
+
+  for (j = 0; j < mb4_relationlist_list_size (relation_lists); j++) {
+    Mb4RelationList relations;
+    char buffer[512]; /* for the GET() macro */
+    unsigned int i;
+
+    relations = mb4_relationlist_list_item (relation_lists, j);
+    if (relations == NULL)
+      return;
+
+    mb4_relation_list_get_targettype (relations, buffer, sizeof (buffer));
+    if (!g_str_equal (buffer, "artist"))
+      continue;
+
+    for (i = 0; i < mb4_relation_list_size (relations); i++) {
+      Mb4Relation relation;
+      Mb4Artist composer;
+
+      relation = mb4_relation_list_item (relations, i);
+      if (relation == NULL)
+        continue;
+
+      mb4_relation_get_type (relation, buffer, sizeof (buffer));
+      if (!g_str_equal (buffer, "composer"))
+        continue;
+
+      composer = mb4_relation_get_artist (relation);
+      if (composer == NULL)
+        continue;
+
+      GET (track->composer, mb4_artist_get_name, composer);
+      GET (track->composer_sortname, mb4_artist_get_sortname, composer);
+    }
+  }
+}
+
+static void
+fill_recording_relations (Mb4Recording recording, TrackDetails *track)
+{
+  Mb4RelationListList relation_lists;
+  unsigned int j;
+
+  relation_lists = mb4_recording_get_relationlistlist (recording);
+  if (relation_lists == NULL)
+    return;
+
+  for (j = 0; j < mb4_relationlist_list_size (relation_lists); j++) {
+    Mb4RelationList relations;
+    char type[512]; /* To hold relationlist target-type and relation type */
+    unsigned int i;
+
+    relations = mb4_relationlist_list_item (relation_lists, j);
+    if (relations == NULL)
+      return;
+
+    mb4_relation_list_get_targettype (relations, type, sizeof (type));
+    if (!g_str_equal (type, "work"))
+      continue;
+
+    for (i = 0; i < mb4_relation_list_size (relations); i++) {
+      Mb4Relation relation;
+      Mb4Work work;
+
+      relation = mb4_relation_list_item (relations, i);
+      if (relation == NULL)
+        continue;
+
+      mb4_relation_get_type (relation, type, sizeof (type));
+      if (!g_str_equal (type, "performance"))
+        continue;
+
+      work = mb4_relation_get_work (relation);
+      fill_work_relations (work, track);
+    }
+  }
+}
+
+static void
 fill_tracks_from_medium (Mb4Medium medium, AlbumDetails *album)
 {
   Mb4TrackList track_list;
@@ -259,15 +348,20 @@ fill_tracks_from_medium (Mb4Medium medium, AlbumDetails *album)
     track->album = album;
 
     track->number = mb4_track_get_position (mbt);
+
+    /* duration from track is more reliable than from recording */
+    track->duration = mb4_track_get_length (mbt) / 1000;
+
     recording = mb4_track_get_recording (mbt);
     if (recording != NULL) {
       GET (track->title, mb4_recording_get_title, recording);
       GET (track->track_id, mb4_recording_get_id, recording);
-      track->duration = mb4_recording_get_length (recording) / 1000;
+      fill_recording_relations (recording, track);
+      if (track->duration == 0)
+        track->duration = mb4_recording_get_length (recording) / 1000;
       credit = mb4_recording_get_artistcredit (recording);
     } else {
       GET (track->title, mb4_track_get_title, mbt);
-      track->duration = mb4_track_get_length (mbt) / 1000;
       credit = mb4_track_get_artistcredit (mbt);
     }
 
@@ -386,13 +480,11 @@ mb4_list_albums (SjMetadata *metadata, char **url, GError **error)
 
   releases = mb4_query_lookup_discid(priv->mb, discid);
 
-  if (releases == NULL) {
+  if (releases == NULL)
     return NULL;
-  }
 
-  if (mb4_release_list_size (releases) == 0) {
+  if (mb4_release_list_size (releases) == 0)
     return NULL;
-  }
 
   for (i = 0; i < mb4_release_list_size (releases); i++) {
     AlbumDetails *album;
@@ -400,13 +492,26 @@ mb4_list_albums (SjMetadata *metadata, char **url, GError **error)
     release = mb4_release_list_item (releases, i);
     if (release) {
       char *releaseid = NULL;
-      Mb4Release full_release;
+      Mb4Release full_release = NULL;
+      Mb4Metadata release_md = NULL;
+      const char *query_entity = "release";
+      char *params_names[] = { "inc" };
+      char *params_values[] = { "artists artist-credits labels recordings \
+release-groups url-rels discids recording-level-rels work-level-rels work-rels \
+artist-rels" };
 
       releaseid = NULL;
       GET(releaseid, mb4_release_get_id, release);
-
-      full_release = mb4_query_lookup_release (priv->mb, releaseid);
+      /* Inorder to get metadata from work and composer relationships
+       * we need to perform a custom query
+       */
+      release_md = mb4_query_query (priv->mb, query_entity, releaseid, "", 1,
+                                    params_names, params_values);
+
+      if (release_md && mb4_metadata_get_release (release_md))
+        full_release = mb4_metadata_get_release (release_md);
       g_free (releaseid);
+
       if (full_release) {
         Mb4MediumList media;
         Mb4Metadata metadata = NULL;
@@ -444,8 +549,8 @@ mb4_list_albums (SjMetadata *metadata, char **url, GError **error)
         }
         mb4_metadata_delete (metadata);
         mb4_medium_list_delete (media);
-        mb4_release_delete (full_release);
       }
+      mb4_metadata_delete (release_md);
     }
   }
   mb4_release_list_delete (releases);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]