1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "MusicInfoTag.h"
10
11 #include "ServiceBroker.h"
12 #include "guilib/LocalizeStrings.h"
13 #include "music/Artist.h"
14 #include "settings/AdvancedSettings.h"
15 #include "settings/Settings.h"
16 #include "settings/SettingsComponent.h"
17 #include "utils/Archive.h"
18 #include "utils/StringUtils.h"
19 #include "utils/Variant.h"
20
21 #include <algorithm>
22
23 using namespace MUSIC_INFO;
24
CMusicInfoTag(void)25 CMusicInfoTag::CMusicInfoTag(void)
26 {
27 Clear();
28 }
29
operator !=(const CMusicInfoTag & tag) const30 bool CMusicInfoTag::operator !=(const CMusicInfoTag& tag) const
31 {
32 if (this == &tag) return false;
33 if (m_strURL != tag.m_strURL) return true;
34 if (m_strTitle != tag.m_strTitle) return true;
35 if (m_bCompilation != tag.m_bCompilation) return true;
36 if (m_artist != tag.m_artist) return true;
37 if (m_albumArtist != tag.m_albumArtist) return true;
38 if (m_strAlbum != tag.m_strAlbum) return true;
39 if (m_iDuration != tag.m_iDuration) return true;
40 if (m_strDiscSubtitle != tag.m_strDiscSubtitle)
41 return true;
42 if (m_iTrack != tag.m_iTrack)
43 return true;
44 if (m_albumReleaseType != tag.m_albumReleaseType) return true;
45 return false;
46 }
47
GetTrackNumber() const48 int CMusicInfoTag::GetTrackNumber() const
49 {
50 return (m_iTrack & 0xffff);
51 }
52
GetDiscNumber() const53 int CMusicInfoTag::GetDiscNumber() const
54 {
55 return (m_iTrack >> 16);
56 }
57
GetTrackAndDiscNumber() const58 int CMusicInfoTag::GetTrackAndDiscNumber() const
59 {
60 return m_iTrack;
61 }
62
GetDuration() const63 int CMusicInfoTag::GetDuration() const
64 {
65 return m_iDuration;
66 }
67
GetTitle() const68 const std::string& CMusicInfoTag::GetTitle() const
69 {
70 return m_strTitle;
71 }
72
GetURL() const73 const std::string& CMusicInfoTag::GetURL() const
74 {
75 return m_strURL;
76 }
77
GetArtist() const78 const std::vector<std::string>& CMusicInfoTag::GetArtist() const
79 {
80 return m_artist;
81 }
82
GetArtistString() const83 const std::string CMusicInfoTag::GetArtistString() const
84 {
85 if (!m_strArtistDesc.empty())
86 return m_strArtistDesc;
87 else if (!m_artist.empty())
88 return StringUtils::Join(m_artist, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator);
89 else
90 return StringUtils::Empty;
91 }
92
GetArtistSort() const93 const std::string& CMusicInfoTag::GetArtistSort() const
94 {
95 return m_strArtistSort;
96 }
97
GetComposerSort() const98 const std::string& CMusicInfoTag::GetComposerSort() const
99 {
100 return m_strComposerSort;
101 }
102
GetAlbum() const103 const std::string& CMusicInfoTag::GetAlbum() const
104 {
105 return m_strAlbum;
106 }
107
GetDiscSubtitle() const108 const std::string& CMusicInfoTag::GetDiscSubtitle() const
109 {
110 return m_strDiscSubtitle;
111 }
112
GetOriginalDate() const113 const std::string& CMusicInfoTag::GetOriginalDate() const
114 {
115 return m_strOriginalDate;
116 }
117
GetOriginalYear() const118 const std::string MUSIC_INFO::CMusicInfoTag::GetOriginalYear() const
119 {
120 return StringUtils::Left(m_strOriginalDate, 4);
121 }
122
GetAlbumId() const123 int CMusicInfoTag::GetAlbumId() const
124 {
125 return m_iAlbumId;
126 }
127
GetAlbumArtist() const128 const std::vector<std::string>& CMusicInfoTag::GetAlbumArtist() const
129 {
130 return m_albumArtist;
131 }
132
GetAlbumArtistString() const133 const std::string CMusicInfoTag::GetAlbumArtistString() const
134 {
135 if (!m_strAlbumArtistDesc.empty())
136 return m_strAlbumArtistDesc;
137 if (!m_albumArtist.empty())
138 return StringUtils::Join(m_albumArtist, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator);
139 else
140 return StringUtils::Empty;
141 }
142
GetAlbumArtistSort() const143 const std::string& CMusicInfoTag::GetAlbumArtistSort() const
144 {
145 return m_strAlbumArtistSort;
146 }
147
GetGenre() const148 const std::vector<std::string>& CMusicInfoTag::GetGenre() const
149 {
150 return m_genre;
151 }
152
GetDatabaseId() const153 int CMusicInfoTag::GetDatabaseId() const
154 {
155 return m_iDbId;
156 }
157
GetType() const158 const std::string &CMusicInfoTag::GetType() const
159 {
160 return m_type;
161 }
162
GetYear() const163 int CMusicInfoTag::GetYear() const
164 {
165 return atoi(GetYearString().c_str());
166 }
167
GetYearString() const168 std::string CMusicInfoTag::GetYearString() const
169 {
170 /* Get year as YYYY from release or original dates depending on setting
171 This is how GUI and by year sorting swiches to using original year.
172 For ripper and non-library items (libray entries have both values):
173 when release date missing try to fallback to original date
174 when original date missing use release date
175 */
176 std::string value;
177 value = GetReleaseYear();
178 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
179 CSettings::SETTING_MUSICLIBRARY_USEORIGINALDATE) ||
180 value.empty())
181 {
182 std::string origvalue = GetOriginalYear();
183 if (!origvalue.empty())
184 return origvalue;
185 }
186 return value;
187 }
188
GetComment() const189 const std::string &CMusicInfoTag::GetComment() const
190 {
191 return m_strComment;
192 }
193
GetMood() const194 const std::string &CMusicInfoTag::GetMood() const
195 {
196 return m_strMood;
197 }
198
GetRecordLabel() const199 const std::string &CMusicInfoTag::GetRecordLabel() const
200 {
201 return m_strRecordLabel;
202 }
203
GetLyrics() const204 const std::string &CMusicInfoTag::GetLyrics() const
205 {
206 return m_strLyrics;
207 }
208
GetCueSheet() const209 const std::string &CMusicInfoTag::GetCueSheet() const
210 {
211 return m_cuesheet;
212 }
213
GetRating() const214 float CMusicInfoTag::GetRating() const
215 {
216 return m_Rating;
217 }
218
GetUserrating() const219 int CMusicInfoTag::GetUserrating() const
220 {
221 return m_Userrating;
222 }
223
GetVotes() const224 int CMusicInfoTag::GetVotes() const
225 {
226 return m_Votes;
227 }
228
GetListeners() const229 int CMusicInfoTag::GetListeners() const
230 {
231 return m_listeners;
232 }
233
GetPlayCount() const234 int CMusicInfoTag::GetPlayCount() const
235 {
236 return m_iTimesPlayed;
237 }
238
GetLastPlayed() const239 const CDateTime &CMusicInfoTag::GetLastPlayed() const
240 {
241 return m_lastPlayed;
242 }
243
GetDateAdded() const244 const CDateTime &CMusicInfoTag::GetDateAdded() const
245 {
246 return m_dateAdded;
247 }
248
GetCompilation() const249 bool CMusicInfoTag::GetCompilation() const
250 {
251 return m_bCompilation;
252 }
253
GetBoxset() const254 bool CMusicInfoTag::GetBoxset() const
255 {
256 return m_bBoxset;
257 }
258
GetTotalDiscs() const259 int CMusicInfoTag::GetTotalDiscs() const
260 {
261 return m_iDiscTotal;
262 }
263
GetCoverArtInfo() const264 const EmbeddedArtInfo &CMusicInfoTag::GetCoverArtInfo() const
265 {
266 return m_coverArt;
267 }
268
GetReplayGain() const269 const ReplayGain& CMusicInfoTag::GetReplayGain() const
270 {
271 return m_replayGain;
272 }
273
GetAlbumReleaseType() const274 CAlbum::ReleaseType CMusicInfoTag::GetAlbumReleaseType() const
275 {
276 return m_albumReleaseType;
277 }
278
GetBPM() const279 int CMusicInfoTag::GetBPM() const
280 {
281 return m_iBPM;
282 }
283
GetBitRate() const284 int CMusicInfoTag::GetBitRate() const
285 {
286 return m_bitrate;
287 }
288
GetSampleRate() const289 int CMusicInfoTag::GetSampleRate() const
290 {
291 return m_samplerate;
292 }
293
GetNoOfChannels() const294 int CMusicInfoTag::GetNoOfChannels() const
295 {
296 return m_channels;
297 }
298
GetReleaseDate() const299 const std::string& CMusicInfoTag::GetReleaseDate() const
300 {
301 return m_strReleaseDate;
302 }
303
GetReleaseYear() const304 const std::string MUSIC_INFO::CMusicInfoTag::GetReleaseYear() const
305 {
306 return StringUtils::Left(m_strReleaseDate, 4);
307 }
308
309 // This is the Musicbrainz release status tag. See https://musicbrainz.org/doc/Release#Status
310
GetAlbumReleaseStatus() const311 const std::string& CMusicInfoTag::GetAlbumReleaseStatus() const
312 {
313 return m_strReleaseStatus;
314 }
315
GetStationName() const316 const std::string& CMusicInfoTag::GetStationName() const
317 {
318 return m_stationName;
319 }
320
GetStationArt() const321 const std::string& CMusicInfoTag::GetStationArt() const
322 {
323 return m_stationArt;
324 }
325
SetURL(const std::string & strURL)326 void CMusicInfoTag::SetURL(const std::string& strURL)
327 {
328 m_strURL = strURL;
329 }
330
SetTitle(const std::string & strTitle)331 void CMusicInfoTag::SetTitle(const std::string& strTitle)
332 {
333 m_strTitle = Trim(strTitle);
334 }
335
SetArtist(const std::string & strArtist)336 void CMusicInfoTag::SetArtist(const std::string& strArtist)
337 {
338 if (!strArtist.empty())
339 {
340 SetArtistDesc(strArtist);
341 SetArtist(StringUtils::Split(strArtist, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
342 }
343 else
344 {
345 m_strArtistDesc.clear();
346 m_artist.clear();
347 }
348 }
349
SetArtist(const std::vector<std::string> & artists,bool FillDesc)350 void CMusicInfoTag::SetArtist(const std::vector<std::string>& artists, bool FillDesc /* = false*/)
351 {
352 m_artist = artists;
353 if (m_strArtistDesc.empty() || FillDesc)
354 {
355 SetArtistDesc(StringUtils::Join(artists, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
356 }
357 }
358
SetArtistDesc(const std::string & strArtistDesc)359 void CMusicInfoTag::SetArtistDesc(const std::string& strArtistDesc)
360 {
361 m_strArtistDesc = strArtistDesc;
362 }
363
SetArtistSort(const std::string & strArtistsort)364 void CMusicInfoTag::SetArtistSort(const std::string& strArtistsort)
365 {
366 m_strArtistSort = strArtistsort;
367 }
368
SetComposerSort(const std::string & strComposerSort)369 void CMusicInfoTag::SetComposerSort(const std::string& strComposerSort)
370 {
371 m_strComposerSort = strComposerSort;
372 }
373
SetAlbum(const std::string & strAlbum)374 void CMusicInfoTag::SetAlbum(const std::string& strAlbum)
375 {
376 m_strAlbum = Trim(strAlbum);
377 }
378
SetAlbumId(const int iAlbumId)379 void CMusicInfoTag::SetAlbumId(const int iAlbumId)
380 {
381 m_iAlbumId = iAlbumId;
382 }
383
SetAlbumArtist(const std::string & strAlbumArtist)384 void CMusicInfoTag::SetAlbumArtist(const std::string& strAlbumArtist)
385 {
386 if (!strAlbumArtist.empty())
387 {
388 SetAlbumArtistDesc(strAlbumArtist);
389 SetAlbumArtist(StringUtils::Split(strAlbumArtist, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
390 }
391 else
392 {
393 m_strAlbumArtistDesc.clear();
394 m_albumArtist.clear();
395 }
396 }
397
SetAlbumArtist(const std::vector<std::string> & albumArtists,bool FillDesc)398 void CMusicInfoTag::SetAlbumArtist(const std::vector<std::string>& albumArtists, bool FillDesc /* = false*/)
399 {
400 m_albumArtist = albumArtists;
401 if (m_strAlbumArtistDesc.empty() || FillDesc)
402 SetAlbumArtistDesc(StringUtils::Join(albumArtists, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
403 }
404
SetAlbumArtistDesc(const std::string & strAlbumArtistDesc)405 void CMusicInfoTag::SetAlbumArtistDesc(const std::string& strAlbumArtistDesc)
406 {
407 m_strAlbumArtistDesc = strAlbumArtistDesc;
408 }
409
SetAlbumArtistSort(const std::string & strAlbumArtistSort)410 void CMusicInfoTag::SetAlbumArtistSort(const std::string& strAlbumArtistSort)
411 {
412 m_strAlbumArtistSort = strAlbumArtistSort;
413 }
414
SetGenre(const std::string & strGenre,bool bTrim)415 void CMusicInfoTag::SetGenre(const std::string& strGenre, bool bTrim /* = false*/)
416 {
417 if (!strGenre.empty())
418 SetGenre(StringUtils::Split(strGenre, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator), bTrim);
419 else
420 m_genre.clear();
421 }
422
SetGenre(const std::vector<std::string> & genres,bool bTrim)423 void CMusicInfoTag::SetGenre(const std::vector<std::string>& genres, bool bTrim /* = false*/)
424 {
425 m_genre = genres;
426 if (bTrim)
427 for (auto genre : m_genre)
428 StringUtils::Trim(genre);
429 }
430
SetYear(int year)431 void CMusicInfoTag::SetYear(int year)
432 {
433 // Parse integer year value into YYYY ISO8601 format (partial) date string
434 // Add century for to 2 digit numbers, 41 -> 1941, 40 -> 2040
435 if (year > 99)
436 SetReleaseDate(StringUtils::Format("%04i", year));
437 else if (year > 40)
438 SetReleaseDate(StringUtils::Format("%04i", 19 + year));
439 else if (year > 0)
440 SetReleaseDate(StringUtils::Format("%04i", 20 + year));
441 else
442 m_strReleaseDate.clear();
443 }
444
SetDatabaseId(int id,const std::string & type)445 void CMusicInfoTag::SetDatabaseId(int id, const std::string &type)
446 {
447 m_iDbId = id;
448 m_type = type;
449 }
450
SetTrackNumber(int iTrack)451 void CMusicInfoTag::SetTrackNumber(int iTrack)
452 {
453 m_iTrack = (m_iTrack & 0xffff0000) | (iTrack & 0xffff);
454 }
455
SetDiscNumber(int iDiscNumber)456 void CMusicInfoTag::SetDiscNumber(int iDiscNumber)
457 {
458 m_iTrack = (m_iTrack & 0xffff) | (iDiscNumber << 16);
459 }
460
SetDiscSubtitle(const std::string & strDiscSubtitle)461 void CMusicInfoTag::SetDiscSubtitle(const std::string& strDiscSubtitle)
462 {
463 m_strDiscSubtitle = strDiscSubtitle;
464 }
465
SetTotalDiscs(int iDiscTotal)466 void CMusicInfoTag::SetTotalDiscs(int iDiscTotal)
467 {
468 m_iDiscTotal = iDiscTotal;
469 }
470
SetReleaseDate(const std::string & strReleaseDate)471 void CMusicInfoTag::SetReleaseDate(const std::string& strReleaseDate)
472 {
473 // Date in ISO8601 YYYY, YYYY-MM or YYYY-MM-DD
474 m_strReleaseDate = strReleaseDate;
475 }
476
SetOriginalDate(const std::string & strOriginalDate)477 void CMusicInfoTag::SetOriginalDate(const std::string& strOriginalDate)
478 {
479 // Date in ISO8601 YYYY, YYYY-MM or YYYY-MM-DD
480 m_strOriginalDate = strOriginalDate;
481 }
482
AddOriginalDate(const std::string & strDateYear)483 void CMusicInfoTag::AddOriginalDate(const std::string& strDateYear)
484 {
485 // Avoid overwriting YYYY-MM or YYYY-MM-DD (from DATE tag) with just YYYY (from YEAR tag)
486 if (strDateYear.size() > m_strOriginalDate.size())
487 m_strOriginalDate = strDateYear;
488 }
489
AddReleaseDate(const std::string & strDateYear,bool isMonth)490 void CMusicInfoTag::AddReleaseDate(const std::string& strDateYear, bool isMonth /*= false*/)
491 {
492 // Given MMDD (from ID3 v2.3 TDAT tag) set MM-DD part of ISO8601 string
493 if (isMonth && !strDateYear.empty())
494 {
495 std::string strYYYY = GetReleaseYear();
496 if (strYYYY.empty())
497 strYYYY = "0000"; // Fake year when TYER not read yet
498 m_strReleaseDate =
499 StringUtils::Format("%s-%s-%s", strYYYY, StringUtils::Left(strDateYear, 2),
500 StringUtils::Right(strDateYear, 2));
501 }
502 // Given YYYY only (from YEAR tag) and already have YYYY-MM or YYYY-MM-DD (from DATE tag)
503 else if (strDateYear.size() == 4 && (m_strReleaseDate.size() > 4))
504 {
505 // Have 0000-MM-DD where ID3 v2.3 TDAT tag read first, fill YYYY part from TYER
506 if (GetReleaseYear() == "0000")
507 StringUtils::Replace(m_strReleaseDate, "0000", strDateYear);
508 }
509 else
510 m_strReleaseDate = strDateYear; // Could be YYYY, YYYY-MM or YYYY-MM-DD
511 }
512
SetTrackAndDiscNumber(int iTrackAndDisc)513 void CMusicInfoTag::SetTrackAndDiscNumber(int iTrackAndDisc)
514 {
515 m_iTrack = iTrackAndDisc;
516 }
517
SetDuration(int iSec)518 void CMusicInfoTag::SetDuration(int iSec)
519 {
520 m_iDuration = iSec;
521 }
522
SetBitRate(int bitrate)523 void CMusicInfoTag::SetBitRate(int bitrate)
524 {
525 m_bitrate = bitrate;
526 }
527
SetNoOfChannels(int channels)528 void CMusicInfoTag::SetNoOfChannels(int channels)
529 {
530 m_channels = channels;
531 }
532
SetSampleRate(int samplerate)533 void CMusicInfoTag::SetSampleRate(int samplerate)
534 {
535 m_samplerate = samplerate;
536 }
537
SetComment(const std::string & comment)538 void CMusicInfoTag::SetComment(const std::string& comment)
539 {
540 m_strComment = comment;
541 }
542
SetMood(const std::string & mood)543 void CMusicInfoTag::SetMood(const std::string& mood)
544 {
545 m_strMood = mood;
546 }
547
SetRecordLabel(const std::string & publisher)548 void CMusicInfoTag::SetRecordLabel(const std::string& publisher)
549 {
550 m_strRecordLabel = publisher;
551 }
552
SetCueSheet(const std::string & cueSheet)553 void CMusicInfoTag::SetCueSheet(const std::string& cueSheet)
554 {
555 m_cuesheet = cueSheet;
556 }
557
SetLyrics(const std::string & lyrics)558 void CMusicInfoTag::SetLyrics(const std::string& lyrics)
559 {
560 m_strLyrics = lyrics;
561 }
562
SetRating(float rating)563 void CMusicInfoTag::SetRating(float rating)
564 {
565 //This value needs to be between 0-10 - 0 will unset the rating
566 rating = std::max(rating, 0.f);
567 rating = std::min(rating, 10.f);
568
569 m_Rating = rating;
570 }
571
SetVotes(int votes)572 void CMusicInfoTag::SetVotes(int votes)
573 {
574 m_Votes = votes;
575 }
576
SetUserrating(int rating)577 void CMusicInfoTag::SetUserrating(int rating)
578 {
579 //This value needs to be between 0-10 - 0 will unset the userrating
580 rating = std::max(rating, 0);
581 rating = std::min(rating, 10);
582
583 m_Userrating = rating;
584 }
585
SetListeners(int listeners)586 void CMusicInfoTag::SetListeners(int listeners)
587 {
588 m_listeners = std::max(listeners, 0);
589 }
590
SetPlayCount(int playcount)591 void CMusicInfoTag::SetPlayCount(int playcount)
592 {
593 m_iTimesPlayed = playcount;
594 }
595
SetLastPlayed(const std::string & lastplayed)596 void CMusicInfoTag::SetLastPlayed(const std::string& lastplayed)
597 {
598 m_lastPlayed.SetFromDBDateTime(lastplayed);
599 }
600
SetLastPlayed(const CDateTime & lastplayed)601 void CMusicInfoTag::SetLastPlayed(const CDateTime& lastplayed)
602 {
603 m_lastPlayed = lastplayed;
604 }
605
SetDateAdded(const std::string & strDateAdded)606 void CMusicInfoTag::SetDateAdded(const std::string& strDateAdded)
607 {
608 m_dateAdded.SetFromDBDateTime(strDateAdded);
609 }
610
SetDateAdded(const CDateTime & dateAdded)611 void CMusicInfoTag::SetDateAdded(const CDateTime& dateAdded)
612 {
613 m_dateAdded = dateAdded;
614 }
615
SetDateUpdated(const std::string & strDateUpdated)616 void MUSIC_INFO::CMusicInfoTag::SetDateUpdated(const std::string& strDateUpdated)
617 {
618 m_dateUpdated.SetFromDBDateTime(strDateUpdated);
619 }
620
SetDateUpdated(const CDateTime & dateUpdated)621 void MUSIC_INFO::CMusicInfoTag::SetDateUpdated(const CDateTime& dateUpdated)
622 {
623 m_dateUpdated = dateUpdated;
624 }
625
SetDateNew(const std::string & strDateNew)626 void MUSIC_INFO::CMusicInfoTag::SetDateNew(const std::string& strDateNew)
627 {
628 m_dateNew.SetFromDBDateTime(strDateNew);
629 }
630
SetDateNew(const CDateTime & dateNew)631 void MUSIC_INFO::CMusicInfoTag::SetDateNew(const CDateTime& dateNew)
632 {
633 m_dateNew = dateNew;
634 }
635
SetCompilation(bool compilation)636 void CMusicInfoTag::SetCompilation(bool compilation)
637 {
638 m_bCompilation = compilation;
639 }
640
SetBoxset(bool boxset)641 void CMusicInfoTag::SetBoxset(bool boxset)
642 {
643 m_bBoxset = boxset;
644 }
645
SetLoaded(bool bOnOff)646 void CMusicInfoTag::SetLoaded(bool bOnOff)
647 {
648 m_bLoaded = bOnOff;
649 }
650
Loaded() const651 bool CMusicInfoTag::Loaded() const
652 {
653 return m_bLoaded;
654 }
655
SetBPM(int bpm)656 void CMusicInfoTag::SetBPM(int bpm)
657 {
658 m_iBPM = bpm;
659 }
660
SetStationName(const std::string & strStationName)661 void CMusicInfoTag::SetStationName(const std::string& strStationName)
662 {
663 m_stationName = strStationName;
664 }
665
GetMusicBrainzTrackID() const666 const std::string& CMusicInfoTag::GetMusicBrainzTrackID() const
667 {
668 return m_strMusicBrainzTrackID;
669 }
670
GetMusicBrainzArtistID() const671 const std::vector<std::string>& CMusicInfoTag::GetMusicBrainzArtistID() const
672 {
673 return m_musicBrainzArtistID;
674 }
675
GetMusicBrainzArtistHints() const676 const std::vector<std::string>& CMusicInfoTag::GetMusicBrainzArtistHints() const
677 {
678 return m_musicBrainzArtistHints;
679 }
680
GetMusicBrainzAlbumID() const681 const std::string& CMusicInfoTag::GetMusicBrainzAlbumID() const
682 {
683 return m_strMusicBrainzAlbumID;
684 }
685
GetMusicBrainzReleaseGroupID() const686 const std::string & MUSIC_INFO::CMusicInfoTag::GetMusicBrainzReleaseGroupID() const
687 {
688 return m_strMusicBrainzReleaseGroupID;
689 }
690
GetMusicBrainzAlbumArtistID() const691 const std::vector<std::string>& CMusicInfoTag::GetMusicBrainzAlbumArtistID() const
692 {
693 return m_musicBrainzAlbumArtistID;
694 }
695
GetMusicBrainzAlbumArtistHints() const696 const std::vector<std::string>& CMusicInfoTag::GetMusicBrainzAlbumArtistHints() const
697 {
698 return m_musicBrainzAlbumArtistHints;
699 }
700
GetMusicBrainzReleaseType() const701 const std::string &CMusicInfoTag::GetMusicBrainzReleaseType() const
702 {
703 return m_strMusicBrainzReleaseType;
704 }
705
SetMusicBrainzTrackID(const std::string & strTrackID)706 void CMusicInfoTag::SetMusicBrainzTrackID(const std::string& strTrackID)
707 {
708 m_strMusicBrainzTrackID = strTrackID;
709 }
710
SetMusicBrainzArtistID(const std::vector<std::string> & musicBrainzArtistId)711 void CMusicInfoTag::SetMusicBrainzArtistID(const std::vector<std::string>& musicBrainzArtistId)
712 {
713 m_musicBrainzArtistID = musicBrainzArtistId;
714 }
715
SetMusicBrainzArtistHints(const std::vector<std::string> & musicBrainzArtistHints)716 void CMusicInfoTag::SetMusicBrainzArtistHints(const std::vector<std::string>& musicBrainzArtistHints)
717 {
718 m_musicBrainzArtistHints = musicBrainzArtistHints;
719 }
720
SetMusicBrainzAlbumID(const std::string & strAlbumID)721 void CMusicInfoTag::SetMusicBrainzAlbumID(const std::string& strAlbumID)
722 {
723 m_strMusicBrainzAlbumID = strAlbumID;
724 }
725
SetMusicBrainzAlbumArtistID(const std::vector<std::string> & musicBrainzAlbumArtistId)726 void CMusicInfoTag::SetMusicBrainzAlbumArtistID(const std::vector<std::string>& musicBrainzAlbumArtistId)
727 {
728 m_musicBrainzAlbumArtistID = musicBrainzAlbumArtistId;
729 }
730
SetMusicBrainzAlbumArtistHints(const std::vector<std::string> & musicBrainzAlbumArtistHints)731 void CMusicInfoTag::SetMusicBrainzAlbumArtistHints(const std::vector<std::string>& musicBrainzAlbumArtistHints)
732 {
733 m_musicBrainzAlbumArtistHints = musicBrainzAlbumArtistHints;
734 }
735
SetMusicBrainzReleaseGroupID(const std::string & strReleaseGroupID)736 void MUSIC_INFO::CMusicInfoTag::SetMusicBrainzReleaseGroupID(const std::string & strReleaseGroupID)
737 {
738 m_strMusicBrainzReleaseGroupID = strReleaseGroupID;
739 }
740
SetMusicBrainzReleaseType(const std::string & ReleaseType)741 void CMusicInfoTag::SetMusicBrainzReleaseType(const std::string& ReleaseType)
742 {
743 m_strMusicBrainzReleaseType = ReleaseType;
744 }
745
SetCoverArtInfo(size_t size,const std::string & mimeType)746 void CMusicInfoTag::SetCoverArtInfo(size_t size, const std::string &mimeType)
747 {
748 m_coverArt.Set(size, mimeType);
749 }
750
SetReplayGain(const ReplayGain & aGain)751 void CMusicInfoTag::SetReplayGain(const ReplayGain& aGain)
752 {
753 m_replayGain = aGain;
754 }
755
SetAlbumReleaseType(CAlbum::ReleaseType releaseType)756 void CMusicInfoTag::SetAlbumReleaseType(CAlbum::ReleaseType releaseType)
757 {
758 m_albumReleaseType = releaseType;
759 }
760
SetType(const MediaType & mediaType)761 void CMusicInfoTag::SetType(const MediaType& mediaType)
762 {
763 m_type = mediaType;
764 }
765
766 // This is the Musicbrainz release status tag. See https://musicbrainz.org/doc/Release#Status
767
SetAlbumReleaseStatus(const std::string & ReleaseStatus)768 void CMusicInfoTag::SetAlbumReleaseStatus(const std::string& ReleaseStatus)
769 {
770 m_strReleaseStatus = ReleaseStatus;
771 }
772
SetStationArt(const std::string & strStationArt)773 void CMusicInfoTag::SetStationArt(const std::string& strStationArt)
774 {
775 m_stationArt = strStationArt;
776 }
777
SetArtist(const CArtist & artist)778 void CMusicInfoTag::SetArtist(const CArtist& artist)
779 {
780 SetArtist(artist.strArtist);
781 SetArtistSort(artist.strSortName);
782 SetAlbumArtist(artist.strArtist);
783 SetAlbumArtistSort(artist.strSortName);
784 SetMusicBrainzArtistID({ artist.strMusicBrainzArtistID });
785 SetMusicBrainzAlbumArtistID({ artist.strMusicBrainzArtistID });
786 SetGenre(artist.genre);
787 SetMood(StringUtils::Join(artist.moods, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
788 SetDateAdded(artist.dateAdded);
789 SetDateUpdated(artist.dateUpdated);
790 SetDateNew(artist.dateNew);
791 SetDatabaseId(artist.idArtist, MediaTypeArtist);
792
793 SetLoaded();
794 }
795
SetAlbum(const CAlbum & album)796 void CMusicInfoTag::SetAlbum(const CAlbum& album)
797 {
798 Clear();
799 //Set all artist infomation from album artist credits and artist description
800 SetArtistDesc(album.GetAlbumArtistString());
801 SetArtist(album.GetAlbumArtist());
802 SetArtistSort(album.GetAlbumArtistSort());
803 SetMusicBrainzArtistID(album.GetMusicBrainzAlbumArtistID());
804 SetAlbumArtistDesc(album.GetAlbumArtistString());
805 SetAlbumArtist(album.GetAlbumArtist());
806 SetAlbumArtistSort(album.GetAlbumArtistSort());
807 SetMusicBrainzAlbumArtistID(album.GetMusicBrainzAlbumArtistID());
808 SetAlbumId(album.idAlbum);
809 SetAlbum(album.strAlbum);
810 SetTitle(album.strAlbum);
811 SetMusicBrainzAlbumID(album.strMusicBrainzAlbumID);
812 SetMusicBrainzReleaseGroupID(album.strReleaseGroupMBID);
813 SetMusicBrainzReleaseType(album.strType);
814 SetAlbumReleaseStatus(album.strReleaseStatus);
815 SetGenre(album.genre);
816 SetMood(StringUtils::Join(album.moods, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
817 SetRecordLabel(album.strLabel);
818 SetRating(album.fRating);
819 SetUserrating(album.iUserrating);
820 SetVotes(album.iVotes);
821 SetCompilation(album.bCompilation);
822 SetOriginalDate(album.strOrigReleaseDate);
823 SetReleaseDate(album.strReleaseDate);
824 SetBoxset(album.bBoxedSet);
825 SetAlbumReleaseType(album.releaseType);
826 SetDateAdded(album.dateAdded);
827 SetDateUpdated(album.dateUpdated);
828 SetDateNew(album.dateNew);
829 SetPlayCount(album.iTimesPlayed);
830 SetDatabaseId(album.idAlbum, MediaTypeAlbum);
831 SetLastPlayed(album.lastPlayed);
832 SetTotalDiscs(album.iTotalDiscs);
833 SetDuration(album.iAlbumDuration);
834
835 SetLoaded();
836 }
837
SetSong(const CSong & song)838 void CMusicInfoTag::SetSong(const CSong& song)
839 {
840 Clear();
841 SetTitle(song.strTitle);
842 SetGenre(song.genre);
843 /* Set all artist infomation from song artist credits and artist description.
844 During processing e.g. Cue Sheets, song may only have artist description string
845 rather than a fully populated artist credits vector.
846 */
847 if (!song.HasArtistCredits())
848 SetArtist(song.GetArtistString()); //Sets both artist description string and artist vector from string
849 else
850 {
851 SetArtistDesc(song.GetArtistString());
852 SetArtist(song.GetArtist());
853 SetMusicBrainzArtistID(song.GetMusicBrainzArtistID());
854 }
855 SetArtistSort(song.GetArtistSort());
856 SetAlbum(song.strAlbum);
857 SetAlbumArtist(song.GetAlbumArtist()); //Only have album artist in song as vector, no desc or MBID
858 SetAlbumArtistSort(song.GetAlbumArtistSort());
859 SetMusicBrainzTrackID(song.strMusicBrainzTrackID);
860 SetContributors(song.GetContributors());
861 SetComment(song.strComment);
862 SetCueSheet(song.strCueSheet);
863 SetPlayCount(song.iTimesPlayed);
864 SetLastPlayed(song.lastPlayed);
865 SetDateAdded(song.dateAdded);
866 SetDateUpdated(song.dateUpdated);
867 SetDateNew(song.dateNew);
868 SetCoverArtInfo(song.embeddedArt.m_size, song.embeddedArt.m_mime);
869 SetRating(song.rating);
870 SetUserrating(song.userrating);
871 SetVotes(song.votes);
872 SetURL(song.strFileName);
873 SetReleaseDate(song.strReleaseDate);
874 SetOriginalDate(song.strOrigReleaseDate);
875 SetTrackAndDiscNumber(song.iTrack);
876 SetDiscSubtitle(song.strDiscSubtitle);
877 SetDuration(song.iDuration);
878 SetMood(song.strMood);
879 SetCompilation(song.bCompilation);
880 SetAlbumId(song.idAlbum);
881 SetDatabaseId(song.idSong, MediaTypeSong);
882 SetBPM(song.iBPM);
883 SetBitRate(song.iBitRate);
884 SetSampleRate(song.iSampleRate);
885 SetNoOfChannels(song.iChannels);
886
887 if (song.replayGain.Get(ReplayGain::TRACK).Valid())
888 m_replayGain.Set(ReplayGain::TRACK, song.replayGain.Get(ReplayGain::TRACK));
889 if (song.replayGain.Get(ReplayGain::ALBUM).Valid())
890 m_replayGain.Set(ReplayGain::ALBUM, song.replayGain.Get(ReplayGain::ALBUM));
891
892 SetLoaded();
893 }
894
Serialize(CVariant & value) const895 void CMusicInfoTag::Serialize(CVariant& value) const
896 {
897 value["url"] = m_strURL;
898 value["title"] = m_strTitle;
899 if (m_type.compare(MediaTypeArtist) == 0 && m_artist.size() == 1)
900 value["artist"] = m_artist[0];
901 else
902 value["artist"] = m_artist;
903 // There are situations where the individual artist(s) are not queried from the song_artist and artist tables e.g. playlist,
904 // only artist description from song table. Since processing of the ARTISTS tag was added the individual artists may not always
905 // be accurately derived by simply splitting the artist desc. Hence m_artist is only populated when the individual artists are
906 // queried, whereas GetArtistString() will always return the artist description.
907 // To avoid empty artist array in JSON, when m_artist is empty then an attempt is made to split the artist desc into artists.
908 // A longer term solution would be to ensure that when individual artists are to be returned then the song_artist and artist tables
909 // are queried.
910 if (m_artist.empty())
911 value["artist"] = StringUtils::Split(GetArtistString(), CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator);
912
913 value["displayartist"] = GetArtistString();
914 value["displayalbumartist"] = GetAlbumArtistString();
915 value["sortartist"] = GetArtistSort();
916 value["album"] = m_strAlbum;
917 value["albumartist"] = m_albumArtist;
918 value["sortalbumartist"] = m_strAlbumArtistSort;
919 value["genre"] = m_genre;
920 value["duration"] = m_iDuration;
921 value["track"] = GetTrackNumber();
922 value["disc"] = GetDiscNumber();
923 value["loaded"] = m_bLoaded;
924 value["year"] = GetYear(); // Optionally from m_strOriginalDate
925 value["musicbrainztrackid"] = m_strMusicBrainzTrackID;
926 value["musicbrainzartistid"] = m_musicBrainzArtistID;
927 value["musicbrainzalbumid"] = m_strMusicBrainzAlbumID;
928 value["musicbrainzreleasegroupid"] = m_strMusicBrainzReleaseGroupID;
929 value["musicbrainzalbumartistid"] = m_musicBrainzAlbumArtistID;
930 value["comment"] = m_strComment;
931 value["contributors"] = CVariant(CVariant::VariantTypeArray);
932 for (const auto& role : m_musicRoles)
933 {
934 CVariant contributor;
935 contributor["name"] = role.GetArtist();
936 contributor["role"] = role.GetRoleDesc();
937 contributor["roleid"] = role.GetRoleId();
938 contributor["artistid"] = (int)(role.GetArtistId());
939 value["contributors"].push_back(contributor);
940 }
941 value["displaycomposer"] = GetArtistStringForRole("composer"); //TCOM
942 value["displayconductor"] = GetArtistStringForRole("conductor"); //TPE3
943 value["displayorchestra"] = GetArtistStringForRole("orchestra");
944 value["displaylyricist"] = GetArtistStringForRole("lyricist"); //TEXT
945 value["mood"] = StringUtils::Split(m_strMood, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator);
946 value["recordlabel"] = m_strRecordLabel;
947 value["rating"] = m_Rating;
948 value["userrating"] = m_Userrating;
949 value["votes"] = m_Votes;
950 value["playcount"] = m_iTimesPlayed;
951 value["lastplayed"] = m_lastPlayed.IsValid() ? m_lastPlayed.GetAsDBDateTime() : StringUtils::Empty;
952 value["dateadded"] = m_dateAdded.IsValid() ? m_dateAdded.GetAsDBDateTime() : StringUtils::Empty;
953 value["datenew"] = m_dateNew.IsValid() ? m_dateNew.GetAsDBDateTime() : StringUtils::Empty;
954 value["datemodified"] =
955 m_dateUpdated.IsValid() ? m_dateUpdated.GetAsDBDateTime() : StringUtils::Empty;
956 value["lyrics"] = m_strLyrics;
957 value["albumid"] = m_iAlbumId;
958 value["compilationartist"] = m_bCompilation;
959 value["compilation"] = m_bCompilation;
960 if (m_type.compare(MediaTypeAlbum) == 0)
961 value["releasetype"] = CAlbum::ReleaseTypeToString(m_albumReleaseType);
962 else if (m_type.compare(MediaTypeSong) == 0)
963 value["albumreleasetype"] = CAlbum::ReleaseTypeToString(m_albumReleaseType);
964 value["isboxset"] = m_bBoxset;
965 value["totaldiscs"] = m_iDiscTotal;
966 value["disctitle"] = m_strDiscSubtitle;
967 value["releasedate"] = m_strReleaseDate;
968 value["originaldate"] = m_strOriginalDate;
969 value["albumstatus"] = m_strReleaseStatus;
970 value["bpm"] = m_iBPM;
971 value["bitrate"] = m_bitrate;
972 value["samplerate"] = m_samplerate;
973 value["channels"] = m_channels;
974 }
975
ToSortable(SortItem & sortable,Field field) const976 void CMusicInfoTag::ToSortable(SortItem& sortable, Field field) const
977 {
978 switch (field)
979 {
980 case FieldTitle:
981 {
982 // make sure not to overwrite an existing path with an empty one
983 std::string title = m_strTitle;
984 if (!title.empty() || sortable.find(FieldTitle) == sortable.end())
985 sortable[FieldTitle] = title;
986 break;
987 }
988 case FieldArtist: sortable[FieldArtist] = m_strArtistDesc; break;
989 case FieldArtistSort: sortable[FieldArtistSort] = m_strArtistSort; break;
990 case FieldAlbum: sortable[FieldAlbum] = m_strAlbum; break;
991 case FieldAlbumArtist: sortable[FieldAlbumArtist] = m_strAlbumArtistDesc; break;
992 case FieldGenre: sortable[FieldGenre] = m_genre; break;
993 case FieldTime: sortable[FieldTime] = m_iDuration; break;
994 case FieldTrackNumber: sortable[FieldTrackNumber] = m_iTrack; break;
995 case FieldTotalDiscs:
996 sortable[FieldTotalDiscs] = m_iDiscTotal;
997 break;
998 case FieldYear:
999 sortable[FieldYear] = GetYear(); // Optionally from m_strOriginalDate
1000 break;
1001 case FieldComment: sortable[FieldComment] = m_strComment; break;
1002 case FieldMoods: sortable[FieldMoods] = m_strMood; break;
1003 case FieldRating: sortable[FieldRating] = m_Rating; break;
1004 case FieldUserRating: sortable[FieldUserRating] = m_Userrating; break;
1005 case FieldVotes: sortable[FieldVotes] = m_Votes; break;
1006 case FieldPlaycount: sortable[FieldPlaycount] = m_iTimesPlayed; break;
1007 case FieldLastPlayed: sortable[FieldLastPlayed] = m_lastPlayed.IsValid() ? m_lastPlayed.GetAsDBDateTime() : StringUtils::Empty; break;
1008 case FieldDateAdded: sortable[FieldDateAdded] = m_dateAdded.IsValid() ? m_dateAdded.GetAsDBDateTime() : StringUtils::Empty; break;
1009 case FieldListeners: sortable[FieldListeners] = m_listeners; break;
1010 case FieldId: sortable[FieldId] = (int64_t)m_iDbId; break;
1011 case FieldOrigDate: sortable[FieldOrigDate] = m_strOriginalDate; break;
1012 case FieldBPM: sortable[FieldBPM] = m_iBPM; break;
1013 default: break;
1014 }
1015 }
1016
Archive(CArchive & ar)1017 void CMusicInfoTag::Archive(CArchive& ar)
1018 {
1019 if (ar.IsStoring())
1020 {
1021 ar << m_strURL;
1022 ar << m_strTitle;
1023 ar << m_artist;
1024 ar << m_strArtistSort;
1025 ar << m_strArtistDesc;
1026 ar << m_strAlbum;
1027 ar << m_albumArtist;
1028 ar << m_strAlbumArtistDesc;
1029 ar << m_genre;
1030 ar << m_iDuration;
1031 ar << m_iTrack;
1032 ar << m_bLoaded;
1033 ar << m_strReleaseDate;
1034 ar << m_strOriginalDate;
1035 ar << m_strMusicBrainzTrackID;
1036 ar << m_musicBrainzArtistID;
1037 ar << m_strMusicBrainzAlbumID;
1038 ar << m_strMusicBrainzReleaseGroupID;
1039 ar << m_musicBrainzAlbumArtistID;
1040 ar << m_strDiscSubtitle;
1041 ar << m_bBoxset;
1042 ar << m_iDiscTotal;
1043 ar << m_strMusicBrainzReleaseType;
1044 ar << m_lastPlayed;
1045 ar << m_dateAdded;
1046 ar << m_strComment;
1047 ar << (int)m_musicRoles.size();
1048 for (const auto& credit : m_musicRoles)
1049 {
1050 ar << credit.GetRoleId();
1051 ar << credit.GetRoleDesc();
1052 ar << credit.GetArtist();
1053 ar << credit.GetArtistId();
1054 }
1055 ar << m_strMood;
1056 ar << m_strRecordLabel;
1057 ar << m_Rating;
1058 ar << m_Userrating;
1059 ar << m_Votes;
1060 ar << m_iTimesPlayed;
1061 ar << m_iAlbumId;
1062 ar << m_iDbId;
1063 ar << m_type;
1064 ar << m_strReleaseStatus;
1065 ar << m_strLyrics;
1066 ar << m_bCompilation;
1067 ar << m_listeners;
1068 ar << m_coverArt;
1069 ar << m_cuesheet;
1070 ar << static_cast<int>(m_albumReleaseType);
1071 ar << m_iBPM;
1072 ar << m_samplerate;
1073 ar << m_bitrate;
1074 ar << m_channels;
1075 }
1076 else
1077 {
1078 ar >> m_strURL;
1079 ar >> m_strTitle;
1080 ar >> m_artist;
1081 ar >> m_strArtistSort;
1082 ar >> m_strArtistDesc;
1083 ar >> m_strAlbum;
1084 ar >> m_albumArtist;
1085 ar >> m_strAlbumArtistDesc;
1086 ar >> m_genre;
1087 ar >> m_iDuration;
1088 ar >> m_iTrack;
1089 ar >> m_bLoaded;
1090 ar >> m_strReleaseDate;
1091 ar >> m_strOriginalDate;
1092 ar >> m_strMusicBrainzTrackID;
1093 ar >> m_musicBrainzArtistID;
1094 ar >> m_strMusicBrainzAlbumID;
1095 ar >> m_strMusicBrainzReleaseGroupID;
1096 ar >> m_musicBrainzAlbumArtistID;
1097 ar >> m_strDiscSubtitle;
1098 ar >> m_bBoxset;
1099 ar >> m_iDiscTotal;
1100 ar >> m_strMusicBrainzReleaseType;
1101 ar >> m_lastPlayed;
1102 ar >> m_dateAdded;
1103 ar >> m_strComment;
1104 int iMusicRolesSize;
1105 ar >> iMusicRolesSize;
1106 m_musicRoles.reserve(iMusicRolesSize);
1107 for (int i = 0; i < iMusicRolesSize; ++i)
1108 {
1109 int idRole;
1110 int idArtist;
1111 std::string strArtist;
1112 std::string strRole;
1113 ar >> idRole;
1114 ar >> strRole;
1115 ar >> strArtist;
1116 ar >> idArtist;
1117 m_musicRoles.emplace_back(idRole, strRole, strArtist, idArtist);
1118 }
1119 ar >> m_strMood;
1120 ar >> m_strRecordLabel;
1121 ar >> m_Rating;
1122 ar >> m_Userrating;
1123 ar >> m_Votes;
1124 ar >> m_iTimesPlayed;
1125 ar >> m_iAlbumId;
1126 ar >> m_iDbId;
1127 ar >> m_type;
1128 ar >> m_strReleaseStatus;
1129 ar >> m_strLyrics;
1130 ar >> m_bCompilation;
1131 ar >> m_listeners;
1132 ar >> m_coverArt;
1133 ar >> m_cuesheet;
1134
1135 int albumReleaseType;
1136 ar >> albumReleaseType;
1137 m_albumReleaseType = static_cast<CAlbum::ReleaseType>(albumReleaseType);
1138 ar >> m_iBPM;
1139 ar >> m_samplerate;
1140 ar >> m_bitrate;
1141 ar >> m_channels;
1142 }
1143 }
1144
Clear()1145 void CMusicInfoTag::Clear()
1146 {
1147 m_strURL.clear();
1148 m_artist.clear();
1149 m_strArtistSort.clear();
1150 m_strComposerSort.clear();
1151 m_strAlbum.clear();
1152 m_albumArtist.clear();
1153 m_genre.clear();
1154 m_strTitle.clear();
1155 m_strMusicBrainzTrackID.clear();
1156 m_musicBrainzArtistID.clear();
1157 m_strMusicBrainzAlbumID.clear();
1158 m_strMusicBrainzReleaseGroupID.clear();
1159 m_musicBrainzAlbumArtistID.clear();
1160 m_strMusicBrainzReleaseType.clear();
1161 m_musicRoles.clear();
1162 m_iDuration = 0;
1163 m_iTrack = 0;
1164 m_bLoaded = false;
1165 m_lastPlayed.Reset();
1166 m_dateAdded.Reset();
1167 m_dateNew.Reset();
1168 m_dateUpdated.Reset();
1169 m_bCompilation = false;
1170 m_bBoxset = false;
1171 m_strDiscSubtitle.clear();
1172 m_strComment.clear();
1173 m_strMood.clear();
1174 m_strRecordLabel.clear();
1175 m_cuesheet.clear();
1176 m_iDbId = -1;
1177 m_type.clear();
1178 m_strReleaseStatus.clear();
1179 m_iTimesPlayed = 0;
1180 m_strReleaseDate.clear();
1181 m_strOriginalDate.clear();
1182 m_iAlbumId = -1;
1183 m_coverArt.Clear();
1184 m_replayGain = ReplayGain();
1185 m_albumReleaseType = CAlbum::Album;
1186 m_listeners = 0;
1187 m_Rating = 0;
1188 m_Userrating = 0;
1189 m_Votes = 0;
1190 m_iDiscTotal = 0;
1191 m_iBPM = 0;
1192 m_samplerate = 0;
1193 m_bitrate = 0;
1194 m_channels = 0;
1195 m_stationName.clear();
1196 m_stationArt.clear();
1197 }
1198
AppendArtist(const std::string & artist)1199 void CMusicInfoTag::AppendArtist(const std::string &artist)
1200 {
1201 for (unsigned int index = 0; index < m_artist.size(); index++)
1202 {
1203 if (StringUtils::EqualsNoCase(artist, m_artist.at(index)))
1204 return;
1205 }
1206
1207 m_artist.push_back(artist);
1208 }
1209
AppendAlbumArtist(const std::string & albumArtist)1210 void CMusicInfoTag::AppendAlbumArtist(const std::string &albumArtist)
1211 {
1212 for (unsigned int index = 0; index < m_albumArtist.size(); index++)
1213 {
1214 if (StringUtils::EqualsNoCase(albumArtist, m_albumArtist.at(index)))
1215 return;
1216 }
1217
1218 m_albumArtist.push_back(albumArtist);
1219 }
1220
AppendGenre(const std::string & genre)1221 void CMusicInfoTag::AppendGenre(const std::string &genre)
1222 {
1223 for (unsigned int index = 0; index < m_genre.size(); index++)
1224 {
1225 if (StringUtils::EqualsNoCase(genre, m_genre.at(index)))
1226 return;
1227 }
1228
1229 m_genre.push_back(genre);
1230 }
1231
AddArtistRole(const std::string & Role,const std::string & strArtist)1232 void CMusicInfoTag::AddArtistRole(const std::string& Role, const std::string& strArtist)
1233 {
1234 if (!strArtist.empty() && !Role.empty())
1235 AddArtistRole(Role, StringUtils::Split(strArtist, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator));
1236 }
1237
AddArtistRole(const std::string & Role,const std::vector<std::string> & artists)1238 void CMusicInfoTag::AddArtistRole(const std::string& Role, const std::vector<std::string>& artists)
1239 {
1240 for (unsigned int index = 0; index < artists.size(); index++)
1241 {
1242 CMusicRole ArtistCredit(Role, Trim(artists.at(index)));
1243 //Prevent duplicate entries
1244 auto credit = find(m_musicRoles.begin(), m_musicRoles.end(), ArtistCredit);
1245 if (credit == m_musicRoles.end())
1246 m_musicRoles.push_back(ArtistCredit);
1247 }
1248 }
1249
AppendArtistRole(const CMusicRole & ArtistRole)1250 void CMusicInfoTag::AppendArtistRole(const CMusicRole& ArtistRole)
1251 {
1252 //Append contributor, no check for duplicates as from database
1253 m_musicRoles.push_back(ArtistRole);
1254 }
1255
GetArtistStringForRole(const std::string & strRole) const1256 const std::string CMusicInfoTag::GetArtistStringForRole(const std::string& strRole) const
1257 {
1258 std::vector<std::string> artistvector;
1259 for (const auto& credit : m_musicRoles)
1260 {
1261 if (StringUtils::EqualsNoCase(credit.GetRoleDesc(), strRole))
1262 artistvector.push_back(credit.GetArtist());
1263 }
1264 return StringUtils::Join(artistvector, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator);
1265 }
1266
GetContributorsText() const1267 const std::string CMusicInfoTag::GetContributorsText() const
1268 {
1269 std::string strLabel;
1270 for (const auto& credit : m_musicRoles)
1271 {
1272 strLabel += StringUtils::Format("%s\n", credit.GetArtist().c_str());
1273 }
1274 return StringUtils::TrimRight(strLabel, "\n");
1275 }
1276
GetContributorsAndRolesText() const1277 const std::string CMusicInfoTag::GetContributorsAndRolesText() const
1278 {
1279 std::string strLabel;
1280 for (const auto& credit : m_musicRoles)
1281 {
1282 strLabel +=
1283 StringUtils::Format("%s - %s\n", credit.GetRoleDesc().c_str(), credit.GetArtist().c_str());
1284 }
1285 return StringUtils::TrimRight(strLabel, "\n");
1286 }
1287
1288
GetContributors() const1289 const VECMUSICROLES &CMusicInfoTag::GetContributors() const
1290 {
1291 return m_musicRoles;
1292 }
1293
SetContributors(const VECMUSICROLES & contributors)1294 void CMusicInfoTag::SetContributors(const VECMUSICROLES& contributors)
1295 {
1296 m_musicRoles = contributors;
1297 }
1298
Trim(const std::string & value) const1299 std::string CMusicInfoTag::Trim(const std::string &value) const
1300 {
1301 std::string trimmedValue(value);
1302 StringUtils::TrimLeft(trimmedValue, " ");
1303 StringUtils::TrimRight(trimmedValue, " \n\r");
1304 return trimmedValue;
1305 }
1306