Skip to content
This repository
Browse code

Merge pull request #2974 from night199uk/musicfixes

[musicdb] Fixes for non-MusicBrainz albums
  • Loading branch information...
commit 8193a5359d133a4cbf4858bf2c95c0bf7d86357a 2 parents 7aca6dd + e54553d
night199uk authored
23  xbmc/music/Album.cpp
@@ -38,6 +38,16 @@ CAlbum::CAlbum(const CFileItem& item)
38 38
   strMusicBrainzAlbumID = tag.GetMusicBrainzAlbumID();
39 39
   genre = tag.GetGenre();
40 40
   artist = tag.GetAlbumArtist();
  41
+  bool hasMusicBrainzAlbumArtist = !tag.GetMusicBrainzAlbumArtistID().empty();
  42
+  const vector<string>& artists = hasMusicBrainzAlbumArtist ? tag.GetMusicBrainzAlbumArtistID() : tag.GetAlbumArtist();
  43
+  for (vector<string>::const_iterator it = artists.begin(); it != artists.end(); ++it)
  44
+  {
  45
+    CStdString artistName = hasMusicBrainzAlbumArtist && !artist.empty() ? artist[0] : *it;
  46
+    CStdString artistId = hasMusicBrainzAlbumArtist ? *it : StringUtils::EmptyString;
  47
+    CStdString strJoinPhrase = (it == --artists.end() ? "" : g_advancedSettings.m_musicItemSeparator);
  48
+    CArtistCredit artistCredit(artistName, artistId, strJoinPhrase);
  49
+    artistCredits.push_back(artistCredit);
  50
+  }
41 51
   iYear = stTime.wYear;
42 52
   bCompilation = tag.GetCompilation();
43 53
   iTimesPlayed = 0;
@@ -55,8 +65,17 @@ CStdString CAlbum::GetGenreString() const
55 65
 
56 66
 bool CAlbum::operator<(const CAlbum &a) const
57 67
 {
58  
-  if (strAlbum < a.strAlbum) return true;
59  
-  if (strAlbum > a.strAlbum) return false;
  68
+  if (strMusicBrainzAlbumID.IsEmpty() && a.strMusicBrainzAlbumID.IsEmpty())
  69
+  {
  70
+    if (strAlbum < a.strAlbum) return true;
  71
+    if (strAlbum > a.strAlbum) return false;
  72
+
  73
+    // This will do an std::vector compare (i.e. item by item)
  74
+    if (artist < a.artist) return true;
  75
+    if (artist > a.artist) return false;
  76
+    return false;
  77
+  }
  78
+
60 79
   if (strMusicBrainzAlbumID < a.strMusicBrainzAlbumID) return true;
61 80
   if (strMusicBrainzAlbumID > a.strMusicBrainzAlbumID) return false;
62 81
   return false;
18  xbmc/music/Artist.h
@@ -36,8 +36,13 @@ class CArtist
36 36
   long idArtist;
37 37
   bool operator<(const CArtist& a) const
38 38
   {
39  
-    if (strArtist < a.strArtist) return true;
40  
-    if (strArtist > a.strArtist) return false;
  39
+    if (strMusicBrainzArtistID.IsEmpty() && a.strMusicBrainzArtistID.IsEmpty())
  40
+    {
  41
+      if (strArtist < a.strArtist) return true;
  42
+      if (strArtist > a.strArtist) return false;
  43
+      return false;
  44
+    }
  45
+
41 46
     if (strMusicBrainzArtistID < a.strMusicBrainzArtistID) return true;
42 47
     if (strMusicBrainzArtistID > a.strMusicBrainzArtistID) return false;
43 48
     return false;
@@ -102,8 +107,13 @@ class CArtistCredit
102 107
   : m_strArtist(strArtist), m_strMusicBrainzArtistID(strMusicBrainzArtistID), m_strJoinPhrase(strJoinPhrase), m_boolFeatured(false)  {  }
103 108
   bool operator<(const CArtistCredit& a) const
104 109
   {
105  
-    if (m_strArtist < a.m_strArtist) return true;
106  
-    if (m_strArtist > a.m_strArtist) return false;
  110
+    if (m_strMusicBrainzArtistID.empty() && a.m_strMusicBrainzArtistID.empty())
  111
+    {
  112
+      if (m_strArtist < a.m_strArtist) return true;
  113
+      if (m_strArtist > a.m_strArtist) return false;
  114
+      return false;
  115
+    }
  116
+
107 117
     if (m_strMusicBrainzArtistID < a.m_strMusicBrainzArtistID) return true;
108 118
     if (m_strMusicBrainzArtistID > a.m_strMusicBrainzArtistID) return false;
109 119
     return false;
36  xbmc/music/MusicDatabase.cpp
@@ -364,12 +364,15 @@ int CMusicDatabase::AddSong(const int idAlbum,
364 364
     bHasKaraoke = CKaraokeLyricsFactory::HasLyrics(strPathAndFileName);
365 365
 #endif
366 366
 
367  
-    strSQL=PrepareSQL("SELECT * FROM song WHERE (idAlbum = %i AND strMusicBrainzTrackID = '%s') OR (idAlbum=%i AND dwFileNameCRC='%ul' AND strTitle='%s' AND strMusicBrainzTrackID IS NULL)",
368  
-                      idAlbum,
369  
-                      strMusicBrainzTrackID.c_str(),
370  
-                      idAlbum,
371  
-                      crc,
372  
-                      strTitle.c_str());
  367
+    if (!strMusicBrainzTrackID.empty())
  368
+      strSQL = PrepareSQL("SELECT * FROM song WHERE idAlbum = %i AND strMusicBrainzTrackID = '%s'",
  369
+                          idAlbum,
  370
+                          strMusicBrainzTrackID.c_str());
  371
+    else
  372
+      strSQL = PrepareSQL("SELECT * FROM song WHERE idAlbum=%i AND dwFileNameCRC='%ul' AND strTitle='%s' AND strMusicBrainzTrackID IS NULL",
  373
+                          idAlbum,
  374
+                          crc,
  375
+                          strTitle.c_str());
373 376
 
374 377
     if (!m_pDS->query(strSQL.c_str()))
375 378
       return -1;
@@ -497,10 +500,13 @@ int CMusicDatabase::AddAlbum(const CStdString& strAlbum, const CStdString& strMu
497 500
     if (NULL == m_pDB.get()) return -1;
498 501
     if (NULL == m_pDS.get()) return -1;
499 502
 
500  
-    strSQL=PrepareSQL("SELECT * FROM album WHERE strMusicBrainzAlbumID = '%s' OR (strArtists = '%s' AND strAlbum like '%s' and strMusicBrainzAlbumID IS NULL)",
501  
-                      strMusicBrainzAlbumID.c_str(),
502  
-                      strArtist.c_str(),
503  
-                      strAlbum.c_str());
  503
+    if (!strMusicBrainzAlbumID.empty())
  504
+      strSQL = PrepareSQL("SELECT * FROM album WHERE strMusicBrainzAlbumID = '%s'",
  505
+                        strMusicBrainzAlbumID.c_str());
  506
+    else
  507
+      strSQL = PrepareSQL("SELECT * FROM album WHERE strArtists = '%s' AND strAlbum like '%s' and strMusicBrainzAlbumID IS NULL",
  508
+                          strArtist.c_str(),
  509
+                          strAlbum.c_str());
504 510
     m_pDS->query(strSQL.c_str());
505 511
 
506 512
     if (m_pDS->num_rows() == 0)
@@ -607,9 +613,13 @@ int CMusicDatabase::AddArtist(const CStdString& strArtist, const CStdString& str
607 613
     if (NULL == m_pDB.get()) return -1;
608 614
     if (NULL == m_pDS.get()) return -1;
609 615
 
610  
-     strSQL = PrepareSQL("SELECT * FROM artist WHERE strMusicBrainzArtistID = '%s' OR (strArtist = '%s' AND strMusicBrainzArtistID IS NULL)",
611  
-                         strMusicBrainzArtistID.IsEmpty() ? "x" : strMusicBrainzArtistID.c_str(),
612  
-                         strArtist.c_str());
  616
+    if (!strMusicBrainzArtistID.empty())
  617
+      strSQL = PrepareSQL("SELECT * FROM artist WHERE strMusicBrainzArtistID = '%s'",
  618
+                          strMusicBrainzArtistID.c_str());
  619
+    else
  620
+      strSQL = PrepareSQL("SELECT * FROM artist WHERE strArtist = '%s' AND strMusicBrainzArtistID IS NULL",
  621
+                          strArtist.c_str());
  622
+
613 623
     m_pDS->query(strSQL.c_str());
614 624
 
615 625
     if (m_pDS->num_rows() == 0)
10  xbmc/music/Song.cpp
@@ -36,6 +36,16 @@ CSong::CSong(CFileItem& item)
36 36
   strTitle = tag.GetTitle();
37 37
   genre = tag.GetGenre();
38 38
   artist = tag.GetArtist();
  39
+  bool hasMusicBrainzArtist = !tag.GetMusicBrainzArtistID().empty();
  40
+  const vector<string>& artists = hasMusicBrainzArtist ? tag.GetMusicBrainzArtistID() : tag.GetArtist();
  41
+  for (vector<string>::const_iterator it = artists.begin(); it != artists.end(); ++it)
  42
+  {
  43
+    CStdString artistName = hasMusicBrainzArtist && !artist.empty() ? artist[0] : *it;
  44
+    CStdString artistId = hasMusicBrainzArtist ? *it : StringUtils::EmptyString;
  45
+    CStdString strJoinPhrase = (it == --artists.end() ? "" : g_advancedSettings.m_musicItemSeparator);
  46
+    CArtistCredit artistCredit(artistName, artistId, strJoinPhrase);
  47
+    artistCredits.push_back(artistCredit);
  48
+  }
39 49
   strAlbum = tag.GetAlbum();
40 50
   albumArtist = tag.GetAlbumArtist();
41 51
   strMusicBrainzTrackID = tag.GetMusicBrainzTrackID();
304  xbmc/music/infoscanner/MusicInfoScanner.cpp
@@ -492,18 +492,28 @@ INFO_RET CMusicInfoScanner::ScanTags(const CFileItemList& items, CFileItemList&
492 492
   return INFO_ADDED;
493 493
 }
494 494
 
  495
+static bool SortSongsByTrack(const CSong& song, const CSong& song2)
  496
+{
  497
+  return song.iTrack < song2.iTrack;
  498
+}
  499
+
495 500
 void CMusicInfoScanner::FileItemsToAlbums(CFileItemList& items, VECALBUMS& albums, MAPSONGS* songsMap /* = NULL */)
496 501
 {
  502
+  /*
  503
+   * Step 1: Convert the FileItems into Songs. 
  504
+   * If they're MB tagged, create albums directly from the FileItems.
  505
+   * If they're non-MB tagged, index them by album name ready for step 2.
  506
+   */
  507
+  map<string, VECSONGS> songsByAlbumNames;
497 508
   for (int i = 0; i < items.Size(); ++i)
498 509
   {
499  
-    CFileItemPtr pItem = items[i];
500  
-    CMusicInfoTag& tag = *pItem->GetMusicInfoTag();
501  
-    CSong song(*pItem);
  510
+    CMusicInfoTag& tag = *items[i]->GetMusicInfoTag();
  511
+    CSong song(*items[i]);
502 512
 
503 513
     // keep the db-only fields intact on rescan...
504 514
     if (songsMap != NULL)
505 515
     {
506  
-      MAPSONGS::iterator it = songsMap->find(pItem->GetPath());
  516
+      MAPSONGS::iterator it = songsMap->find(items[i]->GetPath());
507 517
       if (it != songsMap->end())
508 518
       {
509 519
         song.iTimesPlayed = it->second.iTimesPlayed;
@@ -514,61 +524,143 @@ void CMusicInfoScanner::FileItemsToAlbums(CFileItemList& items, VECALBUMS& album
514 524
       }
515 525
     }
516 526
 
517  
-    if (!tag.GetMusicBrainzArtistID().empty())
  527
+    if (!tag.GetMusicBrainzAlbumID().empty())
518 528
     {
519  
-      for (vector<string>::const_iterator it = tag.GetMusicBrainzArtistID().begin(); it != tag.GetMusicBrainzArtistID().end(); ++it)
  529
+      VECALBUMS::iterator it;
  530
+      for (it = albums.begin(); it != albums.end(); ++it)
  531
+        if (it->strMusicBrainzAlbumID.Equals(tag.GetMusicBrainzAlbumID()))
  532
+          break;
  533
+
  534
+      if (it == albums.end())
520 535
       {
521  
-        CStdString strJoinPhrase = (it == --tag.GetMusicBrainzArtistID().end() ? "" : g_advancedSettings.m_musicItemSeparator);
522  
-        CArtistCredit mbartist(tag.GetArtist().empty() ? "" : tag.GetArtist()[0], *it, strJoinPhrase);
523  
-        song.artistCredits.push_back(mbartist);
  536
+        CAlbum album(*items[i]);
  537
+        album.songs.push_back(song);
  538
+        albums.push_back(album);
524 539
       }
525  
-      song.artist = tag.GetArtist();
  540
+      else
  541
+        it->songs.push_back(song);
526 542
     }
527 543
     else
  544
+      songsByAlbumNames[tag.GetAlbum()].push_back(song);
  545
+  }
  546
+
  547
+  /*
  548
+   Step 2: Split into unique albums based on album name and album artist
  549
+   In the case where the album artist is unknown, we use the primary artist
  550
+   (i.e. first artist from each song).
  551
+   */
  552
+  for (map<string, VECSONGS>::iterator songsByAlbumName = songsByAlbumNames.begin(); songsByAlbumName != songsByAlbumNames.end(); ++songsByAlbumName)
  553
+  {
  554
+    VECSONGS &songs = songsByAlbumName->second;
  555
+    // sort the songs by tracknumber to identify duplicate track numbers
  556
+    sort(songs.begin(), songs.end(), SortSongsByTrack);
  557
+
  558
+    // map the songs to their primary artists
  559
+    bool tracksOverlap = false;
  560
+    bool hasAlbumArtist = false;
  561
+    bool isCompilation = true;
  562
+
  563
+    map<string, vector<CSong *> > artists;
  564
+    for (VECSONGS::iterator song = songs.begin(); song != songs.end(); ++song)
528 565
     {
529  
-      for (vector<string>::const_iterator it = tag.GetArtist().begin(); it != tag.GetArtist().end(); ++it)
  566
+      // test for song overlap
  567
+      if (song != songs.begin() && song->iTrack == (song - 1)->iTrack)
  568
+        tracksOverlap = true;
  569
+
  570
+      if (!song->bCompilation)
  571
+        isCompilation = false;
  572
+
  573
+      // get primary artist
  574
+      string primary;
  575
+      if (!song->albumArtist.empty())
530 576
       {
531  
-        CStdString strJoinPhrase = (it == --tag.GetArtist().end() ? "" : g_advancedSettings.m_musicItemSeparator);
532  
-        CArtistCredit nonmbartist(*it, strJoinPhrase);
533  
-        song.artistCredits.push_back(nonmbartist);
  577
+        primary = song->albumArtist[0];
  578
+        hasAlbumArtist = true;
534 579
       }
535  
-      song.artist = tag.GetArtist();
  580
+      else if (!song->artist.empty())
  581
+        primary = song->artist[0];
  582
+
  583
+      // add to the artist map
  584
+      artists[primary].push_back(&(*song));
  585
+    }
  586
+
  587
+    /*
  588
+     We have a compilation if
  589
+     1. album name is non-empty AND
  590
+     2a. no tracks overlap OR
  591
+     2b. all tracks are marked as part of compilation AND
  592
+     3a. a unique primary artist is specified as "various" or "various artists" OR
  593
+     3b. we have at least two primary artists and no album artist specified.
  594
+     */
  595
+    bool compilation = !songsByAlbumName->first.empty() && (isCompilation || !tracksOverlap); // 1+2b+2a
  596
+    if (artists.size() == 1)
  597
+    {
  598
+      string artist = artists.begin()->first; StringUtils::ToLower(artist);
  599
+      if (!StringUtils::EqualsNoCase(artist, "various") &&
  600
+          !StringUtils::EqualsNoCase(artist, "various artists")) // 3a
  601
+        compilation = false;
536 602
     }
  603
+    else if (hasAlbumArtist) // 3b
  604
+      compilation = false;
537 605
 
538  
-    bool found = false;
539  
-    for (VECALBUMS::iterator it = albums.begin(); it != albums.end(); ++it)
  606
+    if (compilation)
540 607
     {
541  
-      if (it->strAlbum == tag.GetAlbum() && it->strMusicBrainzAlbumID == tag.GetMusicBrainzAlbumID())
  608
+      CLog::Log(LOGDEBUG, "Album '%s' is a compilation as there's no overlapping tracks and %s", songsByAlbumName->first.c_str(), hasAlbumArtist ? "the album artist is 'Various'" : "there is more than one unique artist");
  609
+      artists.clear();
  610
+      std::string various = g_localizeStrings.Get(340); // Various Artists
  611
+      vector<string> va; va.push_back(various);
  612
+      for (VECSONGS::iterator song = songs.begin(); song != songs.end(); ++song)
542 613
       {
543  
-        it->songs.push_back(song);
544  
-        found = true;
  614
+        song->albumArtist = va;
  615
+        artists[various].push_back(&(*song));
545 616
       }
546 617
     }
547  
-    if (!found)
  618
+
  619
+    /*
  620
+     Step 3: Find the common albumartist for each song and assign
  621
+     albumartist to those tracks that don't have it set.
  622
+     */
  623
+    for (map<string, vector<CSong *> >::iterator j = artists.begin(); j != artists.end(); ++j)
548 624
     {
549  
-      CAlbum album(*pItem.get());
550  
-      if (!tag.GetMusicBrainzAlbumArtistID().empty())
  625
+      // find the common artist for these songs
  626
+      vector<CSong *> &artistSongs = j->second;
  627
+      vector<string> common = artistSongs.front()->albumArtist.empty() ? artistSongs.front()->artist : artistSongs.front()->albumArtist;
  628
+      for (vector<CSong *>::iterator k = artistSongs.begin() + 1; k != artistSongs.end(); ++k)
551 629
       {
552  
-        for (vector<string>::const_iterator it = tag.GetMusicBrainzAlbumArtistID().begin(); it != tag.GetMusicBrainzAlbumArtistID().end(); ++it)
  630
+        unsigned int match = 0;
  631
+        vector<string> &compare = (*k)->albumArtist.empty() ? (*k)->artist : (*k)->albumArtist;
  632
+        for (; match < common.size() && match < compare.size(); match++)
553 633
         {
554  
-          // Picard always stored the display artist string in the first artist slot, no need to split it
555  
-          CStdString strJoinPhrase = (it == --tag.GetMusicBrainzAlbumArtistID().end() ? "" : g_advancedSettings.m_musicItemSeparator);
556  
-          CArtistCredit mbartist(tag.GetAlbumArtist().empty() ? "" : tag.GetAlbumArtist()[0], *it, strJoinPhrase);
557  
-          album.artistCredits.push_back(mbartist);
  634
+          if (compare[match] != common[match])
  635
+            break;
558 636
         }
559  
-        album.artist = tag.GetAlbumArtist();
  637
+        common.erase(common.begin() + match, common.end());
560 638
       }
561  
-      else
  639
+
  640
+      /*
  641
+       Step 4: Assign the album artist for each song that doesn't have it set
  642
+       and add to the album vector
  643
+       */
  644
+      CAlbum album;
  645
+      album.strAlbum = songsByAlbumName->first;
  646
+      album.artist = common;
  647
+      for (vector<string>::iterator it = common.begin(); it != common.end(); ++it)
562 648
       {
563  
-        for (vector<string>::const_iterator it = tag.GetAlbumArtist().begin(); it != tag.GetAlbumArtist().end(); ++it)
564  
-        {
565  
-          CStdString strJoinPhrase = (it == --tag.GetAlbumArtist().end() ? "" : g_advancedSettings.m_musicItemSeparator);
566  
-          CArtistCredit nonmbartist(*it, strJoinPhrase);
567  
-          album.artistCredits.push_back(nonmbartist);
568  
-        }
569  
-        album.artist = tag.GetAlbumArtist();
  649
+        CStdString strJoinPhrase = (it == --common.end() ? "" : g_advancedSettings.m_musicItemSeparator);
  650
+        CArtistCredit artistCredit(*it, strJoinPhrase);
  651
+        album.artistCredits.push_back(artistCredit);
  652
+      }
  653
+      album.bCompilation = compilation;
  654
+      for (vector<CSong *>::iterator k = artistSongs.begin(); k != artistSongs.end(); ++k)
  655
+      {
  656
+        if ((*k)->albumArtist.empty())
  657
+          (*k)->albumArtist = common;
  658
+        // TODO: in future we may wish to union up the genres, for now we assume they're the same
  659
+        album.genre = (*k)->genre;
  660
+        //       in addition, we may want to use year as discriminating for albums
  661
+        album.iYear = (*k)->iYear;
  662
+        album.songs.push_back(**k);
570 663
       }
571  
-      album.songs.push_back(song);
572 664
       albums.push_back(album);
573 665
     }
574 666
   }
@@ -588,8 +680,6 @@ int CMusicInfoScanner::RetrieveMusicInfo(const CStdString& strDirectory, CFileIt
588 680
 
589 681
   VECALBUMS albums;
590 682
   FileItemsToAlbums(scannedItems, albums, &songsMap);
591  
-  if (!(m_flags & SCAN_ONLINE))
592  
-    FixupAlbums(albums);
593 683
   FindArtForAlbums(albums, items.GetPath());
594 684
 
595 685
   int numAdded = 0;
@@ -805,140 +895,6 @@ int CMusicInfoScanner::RetrieveMusicInfo(const CStdString& strDirectory, CFileIt
805 895
   return numAdded;
806 896
 }
807 897
 
808  
-static bool SortSongsByTrack(const CSong& song, const CSong& song2)
809  
-{
810  
-  return song.iTrack < song2.iTrack;
811  
-}
812  
-
813  
-void CMusicInfoScanner::FixupAlbums(VECALBUMS &albums)
814  
-{
815  
-  /*
816  
-   Step 2: Split into unique albums based on album name and album artist
817  
-   In the case where the album artist is unknown, we use the primary artist
818  
-   (i.e. first artist from each song).
819  
-   */
820  
-  for (VECALBUMS::iterator album = albums.begin(); album != albums.end(); ++album)
821  
-  {
822  
-    /*
823  
-     * If we have a valid MusicBrainz tag for the album, assume everything
824  
-     * is okay with our tags, as Picard should set everything up correctly.
825  
-     */
826  
-    if (!album->strMusicBrainzAlbumID.IsEmpty())
827  
-      continue;
828  
-
829  
-    VECSONGS &songs = album->songs;
830  
-    // sort the songs by tracknumber to identify duplicate track numbers
831  
-    sort(songs.begin(), songs.end(), SortSongsByTrack);
832  
-
833  
-    // map the songs to their primary artists
834  
-    bool tracksOverlap = false;
835  
-    bool hasAlbumArtist = false;
836  
-    bool isCompilation = true;
837  
-
838  
-    map<string, vector<CSong *> > artists;
839  
-    for (VECSONGS::iterator song = songs.begin(); song != songs.end(); ++song)
840  
-    {
841  
-      // test for song overlap
842  
-      if (song != songs.begin() && song->iTrack == (song - 1)->iTrack)
843  
-        tracksOverlap = true;
844  
-
845  
-      if (!song->bCompilation)
846  
-        isCompilation = false;
847  
-
848  
-      // get primary artist
849  
-      string primary;
850  
-      if (!song->albumArtist.empty())
851  
-      {
852  
-        primary = song->albumArtist[0];
853  
-        hasAlbumArtist = true;
854  
-      }
855  
-      else if (!song->artist.empty())
856  
-        primary = song->artist[0];
857  
-
858  
-      // add to the artist map
859  
-      artists[primary].push_back(&(*song));
860  
-    }
861  
-
862  
-    /*
863  
-     We have a compilation if
864  
-     1. album name is non-empty AND
865  
-     2a. no tracks overlap OR
866  
-     2b. all tracks are marked as part of compilation AND
867  
-     3a. a unique primary artist is specified as "various" or "various artists" OR
868  
-     3b. we have at least two primary artists and no album artist specified.
869  
-     */
870  
-    bool compilation = !album->strAlbum.empty() && (isCompilation || !tracksOverlap); // 1+2b+2a
871  
-    if (artists.size() == 1)
872  
-    {
873  
-      string artist = artists.begin()->first; StringUtils::ToLower(artist);
874  
-      if (!StringUtils::EqualsNoCase(artist, "various") &&
875  
-          !StringUtils::EqualsNoCase(artist, "various artists")) // 3a
876  
-        compilation = false;
877  
-    }
878  
-    else if (hasAlbumArtist) // 3b
879  
-      compilation = false;
880  
-
881  
-    if (compilation)
882  
-    {
883  
-      CLog::Log(LOGDEBUG, "Album '%s' is a compilation as there's no overlapping tracks and %s", album->strAlbum.c_str(), hasAlbumArtist ? "the album artist is 'Various'" : "there is more than one unique artist");
884  
-      artists.clear();
885  
-      std::string various = g_localizeStrings.Get(340); // Various Artists
886  
-      vector<string> va; va.push_back(various);
887  
-      for (VECSONGS::iterator song = songs.begin(); song != songs.end(); ++song)
888  
-      {
889  
-        song->albumArtist = va;
890  
-        artists[various].push_back(&(*song));
891  
-      }
892  
-    }
893  
-
894  
-    /*
895  
-     Step 3: Find the common albumartist for each song and assign
896  
-     albumartist to those tracks that don't have it set.
897  
-     */
898  
-    for (map<string, vector<CSong *> >::iterator j = artists.begin(); j != artists.end(); ++j)
899  
-    {
900  
-      // find the common artist for these songs
901  
-      vector<CSong *> &artistSongs = j->second;
902  
-      vector<string> common = artistSongs.front()->albumArtist.empty() ? artistSongs.front()->artist : artistSongs.front()->albumArtist;
903  
-      for (vector<CSong *>::iterator k = artistSongs.begin() + 1; k != artistSongs.end(); ++k)
904  
-      {
905  
-        unsigned int match = 0;
906  
-        vector<string> &compare = (*k)->albumArtist.empty() ? (*k)->artist : (*k)->albumArtist;
907  
-        for (; match < common.size() && match < compare.size(); match++)
908  
-        {
909  
-          if (compare[match] != common[match])
910  
-            break;
911  
-        }
912  
-        common.erase(common.begin() + match, common.end());
913  
-      }
914  
-
915  
-      /*
916  
-       Step 4: Assign the album artist for each song that doesn't have it set
917  
-       and add to the album vector
918  
-       */
919  
-      album->artistCredits.clear();
920  
-      for (vector<string>::iterator it = common.begin(); it != common.end(); ++it)
921  
-      {
922  
-        CStdString strJoinPhrase = (it == --common.end() ? "" : g_advancedSettings.m_musicItemSeparator);
923  
-        CArtistCredit artistCredit(*it, strJoinPhrase);
924  
-        album->artistCredits.push_back(artistCredit);
925  
-      }
926  
-      album->bCompilation = compilation;
927  
-      for (vector<CSong *>::iterator k = artistSongs.begin(); k != artistSongs.end(); ++k)
928  
-      {
929  
-        if ((*k)->albumArtist.empty())
930  
-          (*k)->albumArtist = common;
931  
-        // TODO: in future we may wish to union up the genres, for now we assume they're the same
932  
-        if (album->genre.empty())
933  
-          album->genre = (*k)->genre;
934  
-        //       in addition, we may want to use year as discriminating for albums
935  
-        if (album->iYear == 0)
936  
-          album->iYear = (*k)->iYear;
937  
-      }
938  
-    }
939  
-  }
940  
-}
941  
-
942 898
 void CMusicInfoScanner::FindArtForAlbums(VECALBUMS &albums, const CStdString &path)
943 899
 {
944 900
   /*

0 notes on commit 8193a53

Please sign in to comment.
Something went wrong with that request. Please try again.