-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Feature: Rating from id3 popm frame translates into star ratings. #924
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,7 @@ static_assert(sizeof(wchar_t) == sizeof(QChar), "wchar_t is not the same size th | |
#include <taglib/textidentificationframe.h> | ||
#include <taglib/attachedpictureframe.h> | ||
#include <taglib/flacpicture.h> | ||
#include "controlobject.h" | ||
|
||
namespace Mixxx { | ||
|
||
|
@@ -838,6 +839,32 @@ void readTrackMetadataFromID3v2Tag(TrackMetadata* pTrackMetadata, | |
parseTrackPeak(pTrackMetadata, | ||
toQString(pTrackPeakFrame->fieldList()[1])); | ||
} | ||
TagLib::ID3v2::FrameList ratingFrame = tag.frameListMap()["POPM"]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // POPM = Popularimeter |
||
int rating = 0; | ||
|
||
// const int ratingbool = ControlObject::getControl(ConfigKey("[Library]","ID3RatingSync")); | ||
//qDebug() << "ID3 " << ratingbool; | ||
if(!ratingFrame.isEmpty()) { | ||
// RatingString "traktor@native-instruments.de rating=255 counter=2" | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like the tractor format does not apply to the POPM standard: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drat, forgot about that example RatingString. Eh, it works on Windows Media player rated mp3's, at least. |
||
QString sRating = TStringToQString(ratingFrame.front()->toString()); | ||
sRating = sRating.section("=",1,2).left(3); | ||
float fRating = sRating.toInt(); | ||
rating = ceil(fRating/51); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we want to write back the metadadata one day, it is Important not to loose information during the round trip in Mixxx. So we should do the mapping to stars only when we display the data. Here, I think a data structure like this will help:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. QMap? Why create a hash, here? also doesn't seem to be associating with the current track. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With you idea of not connecting ratings with stars automatically, but only if flagged, we'd need to have a new column in the track table called iRating or similar? this wouldn't work so well though, as searching for rating "rating:>3" would pull mixxx's internal only star rating, wouldn't pick up the id3 rating. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because you are able to store multiple independent ratings. Each rating belongs to an e-mail address. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well, this is a problem then. How does the code decide which rating to use for its star rating display? and as far as i know, metatags are only read in on a forced reload or new file.. a library scanner didn't even refresh the rating. How do you store a Qmap/hash in the database? how would you use the library search to search for rated files in stars, when its not stored in stars? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would keep it simple: The Mixxx database should keep track of the Mixxx ratings. Adopting foreign ratings need an explicit user action like:
This can be simplified with a second read only column that just displays the mean value of any external rating found. Or we implement both. |
||
|
||
// Calc rating | ||
// | ||
// NI - Rating | ||
// 255 = 5 | 204 = 4 | 153 = 3 | 102 = 2 | 51 = 1 | 0 = 0 | ||
// | ||
// Banshee - Rating | ||
// 255 = 5 | 192 = 4 | 128 = 3 | 64 = 2 | 1 = 1 | ||
// | ||
// ==> Rating = ceil ( X / 51 ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has mapping has to be justified by more examples. If it works for 2 applications it may fail for the 3rd. Ratings are a really complicated topic if you study the various file formats. Not taking into account the various interpretations and implementation of the standards that can be found in applications. This is the reason why I kept the Mixxx-specific rating in TrackInfoObject. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMHO we should just linear map the rating to a double 0.0 - 5.0 and change the Mixxx DB field to double. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When using an internal floating-point representation I would prefer normalized internal ranges like [0.0, 1.0] for asysmmetric (e.g. "rating") and [-1.0, 1.0] for symmetric values. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, i failed at maths at school. Have no idea how that would work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normally I would prefer the [0.0, 1.0] as well. If we keep the [0.0, 5.0] range, we can keep the library column, because sqlite does not distinguish between int and double internal anyway. |
||
|
||
qDebug() << "Final int() Rating" << rating; | ||
pTrackMetadata->setRating(rating); | ||
} | ||
} | ||
|
||
void readTrackMetadataFromAPETag(TrackMetadata* pTrackMetadata, const TagLib::APE::Tag& tag) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -783,13 +783,14 @@ bool TrackInfoObject::isDirty() { | |
|
||
int TrackInfoObject::getRating() const { | ||
QMutexLocker lock(&m_qMutex); | ||
return m_iRating; | ||
return m_metadata.getRating(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mixxx rating can be != Traktor rating for some users or files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, daschuer, can you make the necessary changes? Not sure how to go about them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have other projects on my todo list. Currently I am working on the native Jack interface. Such a 'sync rating to stars' option seam to work. I am only unsure how we have to deal with the email address. Do we need to expose it to the user? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think, display of the email address is unnecessary in this case. With Windows media player, and some taggers, they don't even save a email address in that field, but a string about the app. Windows media player puts "Windows Media 9 Series rating=128 counter=0" for its 3 star rating. I need some traktor rated files, anyone able to provide? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If Mixxx silently ignores and discards this application-specific string, users may lose their ratings in those applications after tags have been written back by Mixxx. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does Windows media player behave if there is an embedded rating with a foreign email field? Banshee ignored the rating if I change "Banshee" to "Mixxx ", which is correct in the first place, but is not what the user might expect. He might want to use the ID3 tag to see or even synchronize ratings among several media players. In my personal use case, Mixxx is not my main media player. I use Clementine together with my family. An other DJ has a second mixing app along with Mixxx (I can't think of a reason why) he might want to keep the ratings in sync. If we want to do that, I think there is now way around exposing the Email field to the user. |
||
} | ||
|
||
void TrackInfoObject::setRating (int rating) { | ||
QMutexLocker lock(&m_qMutex); | ||
if (compareAndSet(&m_iRating, rating)) { | ||
markDirtyAndUnlock(&lock); | ||
if (m_metadata.getRating() != rating ) { | ||
m_metadata.setRating(rating); | ||
markDirtyAndUnlock(&lock); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TrackMetadata stores tags from various file formats in a portable way, both for reading and writing. I don't recommend to implement it in a way that just works for some special cases and loses information when writing tags back to files as Daniel already mentioned.
The int-rating in Mixxx is just the number of stars displayed on the UI. A portable solution needs to provide a bidirectional mapping between the tags from various file formats and the internal representation.