Handle synthesizing missing tag values in TrackTags instead of the indexer

custom
jacqueline 4 months ago
parent 407d2da049
commit b6b62cb8ea
  1. 5
      src/tangara/database/index.cpp
  2. 32
      src/tangara/database/track.cpp
  3. 2
      src/tangara/database/track.hpp

@ -116,13 +116,12 @@ class Indexer {
case Tag::kTitle: case Tag::kTitle:
return titleOrFilename(track_data_, track_tags_); return titleOrFilename(track_data_, track_tags_);
case Tag::kArtist: case Tag::kArtist:
case Tag::kAlbumArtist:
return "Unknown Artist"; return "Unknown Artist";
case Tag::kAlbum: case Tag::kAlbum:
return "Unknown Album"; return "Unknown Album";
case Tag::kAlbumArtist:
return track_tags_.artist().value_or("Unknown Artist");
case Tag::kAllArtists: case Tag::kAllArtists:
return track_tags_.artist().value_or("Unknown Artist"); return std::pmr::vector<std::pmr::string>{};
case Tag::kGenres: case Tag::kGenres:
return std::pmr::vector<std::pmr::string>{}; return std::pmr::vector<std::pmr::string>{};
case Tag::kDisc: case Tag::kDisc:

@ -155,23 +155,23 @@ auto valueOrMonostate(std::optional<T> t) -> TagValue {
auto TrackTags::get(Tag t) const -> TagValue { auto TrackTags::get(Tag t) const -> TagValue {
switch (t) { switch (t) {
case Tag::kTitle: case Tag::kTitle:
return valueOrMonostate(title_); return valueOrMonostate(title());
case Tag::kArtist: case Tag::kArtist:
return valueOrMonostate(artist_); return valueOrMonostate(artist());
case Tag::kAllArtists: case Tag::kAllArtists:
return allArtists_; return allArtists();
case Tag::kAlbum: case Tag::kAlbum:
return valueOrMonostate(album_); return valueOrMonostate(album());
case Tag::kAlbumArtist: case Tag::kAlbumArtist:
return valueOrMonostate(album_artist_); return valueOrMonostate(albumArtist());
case Tag::kDisc: case Tag::kDisc:
return valueOrMonostate(disc_); return valueOrMonostate(disc());
case Tag::kTrack: case Tag::kTrack:
return valueOrMonostate(track_); return valueOrMonostate(track());
case Tag::kAlbumOrder: case Tag::kAlbumOrder:
return albumOrder(); return albumOrder();
case Tag::kGenres: case Tag::kGenres:
return genres_; return genres();
} }
return std::monostate{}; return std::monostate{};
} }
@ -240,6 +240,7 @@ auto TrackTags::artist() const -> const std::optional<std::pmr::string>& {
auto TrackTags::artist(std::string_view s) -> void { auto TrackTags::artist(std::string_view s) -> void {
artist_ = s; artist_ = s;
maybeSynthesizeAllArtists();
} }
auto TrackTags::allArtists() const -> std::span<const std::pmr::string> { auto TrackTags::allArtists() const -> std::span<const std::pmr::string> {
@ -248,6 +249,7 @@ auto TrackTags::allArtists() const -> std::span<const std::pmr::string> {
auto TrackTags::allArtists(const std::string_view s) -> void { auto TrackTags::allArtists(const std::string_view s) -> void {
parseDelimitedTags(s, kAllArtistDelimiters, allArtists_); parseDelimitedTags(s, kAllArtistDelimiters, allArtists_);
maybeSynthesizeAllArtists();
} }
auto TrackTags::album() const -> const std::optional<std::pmr::string>& { auto TrackTags::album() const -> const std::optional<std::pmr::string>& {
@ -259,6 +261,9 @@ auto TrackTags::album(std::string_view s) -> void {
} }
auto TrackTags::albumArtist() const -> const std::optional<std::pmr::string>& { auto TrackTags::albumArtist() const -> const std::optional<std::pmr::string>& {
if (!album_artist_) {
return artist_;
}
return album_artist_; return album_artist_;
} }
@ -320,6 +325,17 @@ auto TrackTags::Hash() const -> uint64_t {
return komihash_stream_final(&stream); return komihash_stream_final(&stream);
} }
/*
* Adds the current 'artist' tag to 'allArtists' if needed. Many tracks lack a
* fine-grained 'ARTISTS=' tag (or equivalent), but pushing down this nuance to
* consumers of TrackTags adds a lot of complexity.
*/
auto TrackTags::maybeSynthesizeAllArtists() -> void {
if (allArtists_.empty() && artist_) {
allArtists_.push_back(*artist_);
}
}
auto database::TrackData::clone() const -> std::shared_ptr<TrackData> { auto database::TrackData::clone() const -> std::shared_ptr<TrackData> {
auto data = std::make_shared<TrackData>(); auto data = std::make_shared<TrackData>();
data->id = id; data->id = id;

@ -144,6 +144,8 @@ class TrackTags {
auto Hash() const -> uint64_t; auto Hash() const -> uint64_t;
private: private:
auto maybeSynthesizeAllArtists() -> void;
Container encoding_; Container encoding_;
std::optional<std::pmr::string> title_; std::optional<std::pmr::string> title_;

Loading…
Cancel
Save