Change the fields in Song from seconds to nanoseconds
This commit is contained in:
parent
37618dae96
commit
507c5e2632
|
@ -298,5 +298,6 @@
|
|||
<file>schema/schema-26.sql</file>
|
||||
<file>pythonstartup.py</file>
|
||||
<file>schema/schema-27.sql</file>
|
||||
<file>schema/schema-28.sql</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
UPDATE %allsongstables SET length=length*1e9, beginning=beginning*1e9;
|
||||
|
||||
UPDATE schema_version SET version=28;
|
|
@ -31,7 +31,7 @@
|
|||
#include <QVariant>
|
||||
|
||||
const char* Database::kDatabaseFilename = "clementine.db";
|
||||
const int Database::kSchemaVersion = 27;
|
||||
const int Database::kSchemaVersion = 28;
|
||||
const char* Database::kMagicAllSongsTables = "%allsongstables";
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
|
|
|
@ -302,8 +302,8 @@ QVariantMap Mpris1::GetMetadata(const Song& song) {
|
|||
AddMetadata("title", song.PrettyTitle(), &ret);
|
||||
AddMetadata("artist", song.artist(), &ret);
|
||||
AddMetadata("album", song.album(), &ret);
|
||||
AddMetadata("time", song.length(), &ret);
|
||||
AddMetadata("mtime", song.length() * 1000, &ret);
|
||||
AddMetadata("time", song.length_nanosec() / 1e9, &ret);
|
||||
AddMetadata("mtime", song.length_nanosec() / 1e6, &ret);
|
||||
AddMetadata("tracknumber", song.track(), &ret);
|
||||
AddMetadata("year", song.year(), &ret);
|
||||
AddMetadata("genre", song.genre(), &ret);
|
||||
|
|
|
@ -131,7 +131,7 @@ public:
|
|||
|
||||
void VolumeSet(int volume);
|
||||
int VolumeGet() const;
|
||||
void PositionSet(int pos);
|
||||
void PositionSet(int pos_msec);
|
||||
int PositionGet() const;
|
||||
QVariantMap GetMetadata() const;
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ void Mpris2::ArtLoaded(const Song& song, const QString& art_uri) {
|
|||
AddMetadataAsList("xesam:artist", song.artist(), &last_metadata_);
|
||||
AddMetadata("xesam:album", song.album(), &last_metadata_);
|
||||
AddMetadataAsList("xesam:albumArtist", song.albumartist(), &last_metadata_);
|
||||
AddMetadata("mpris:length", song.length()*1e6, &last_metadata_);
|
||||
AddMetadata("mpris:length", song.length_nanosec() / 1e3, &last_metadata_);
|
||||
AddMetadata("xesam:trackNumber", song.track(), &last_metadata_);
|
||||
AddMetadataAsList("xesam:genre", song.genre(), &last_metadata_);
|
||||
AddMetadata("xesam:discNumber", song.disc(), &last_metadata_);
|
||||
|
@ -325,7 +325,7 @@ void Mpris2::SetVolume(double value) {
|
|||
}
|
||||
|
||||
qlonglong Mpris2::Position() const {
|
||||
return mpris1_->player()->PositionGet() / 1e3;
|
||||
return player_->engine()->position_nanosec() / 1e3;
|
||||
}
|
||||
|
||||
double Mpris2::MaximumRate() const {
|
||||
|
@ -408,7 +408,7 @@ void Mpris2::SetPosition(const QDBusObjectPath& trackId, qlonglong offset) {
|
|||
if (CanSeek() && trackId.path() == current_track_id() && offset >= 0) {
|
||||
offset *= 1e3;
|
||||
|
||||
if(offset < player_->GetCurrentItem()->Metadata().length()) {
|
||||
if(offset < player_->GetCurrentItem()->Metadata().length_nanosec()) {
|
||||
player_->Seek(offset / 1e9);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ QString OrganiseFormat::TagValue(const QString &tag, const Song &song) const {
|
|||
else if (tag == "track") value = QString::number(song.track());
|
||||
else if (tag == "disc") value = QString::number(song.disc());
|
||||
else if (tag == "bpm") value = QString::number(song.bpm());
|
||||
else if (tag == "length") value = QString::number(song.length());
|
||||
else if (tag == "length") value = QString::number(song.length_nanosec() / 1e9);
|
||||
else if (tag == "bitrate") value = QString::number(song.bitrate());
|
||||
else if (tag == "samplerate") value = QString::number(song.samplerate());
|
||||
else if (tag == "extension") value = song.filename().section('.', -1, -1);
|
||||
|
|
|
@ -96,8 +96,8 @@ void Player::HandleSpecialLoad(const PlaylistItem::SpecialLoadResult &result) {
|
|||
return;
|
||||
|
||||
engine_->Play(result.media_url_, stream_change_type_,
|
||||
item->Metadata().beginning() * 1e9,
|
||||
item->Metadata().end() * 1e9);
|
||||
item->Metadata().beginning_nanosec(),
|
||||
item->Metadata().end_nanosec());
|
||||
|
||||
current_item_ = item;
|
||||
loading_async_ = QUrl();
|
||||
|
@ -266,8 +266,8 @@ void Player::PlayAt(int index, Engine::TrackChangeType change, bool reshuffle) {
|
|||
else {
|
||||
loading_async_ = QUrl();
|
||||
engine_->Play(current_item_->Url(), change,
|
||||
current_item_->Metadata().beginning() * 1e9,
|
||||
current_item_->Metadata().end() * 1e9);
|
||||
current_item_->Metadata().beginning_nanosec(),
|
||||
current_item_->Metadata().end_nanosec());
|
||||
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
if (lastfm_->IsScrobblingEnabled())
|
||||
|
|
|
@ -201,17 +201,19 @@ Song::Song(FileRefFactory* factory)
|
|||
factory_(factory) {
|
||||
}
|
||||
|
||||
void Song::Init(const QString& title, const QString& artist, const QString& album, int length) {
|
||||
void Song::Init(const QString& title, const QString& artist,
|
||||
const QString& album, qint64 length) {
|
||||
d->valid_ = true;
|
||||
|
||||
d->title_ = title;
|
||||
d->artist_ = artist;
|
||||
d->album_ = album;
|
||||
|
||||
set_length(length);
|
||||
set_length_nanosec(length);
|
||||
}
|
||||
|
||||
void Song::Init(const QString& title, const QString& artist, const QString& album, int beginning, int end) {
|
||||
void Song::Init(const QString& title, const QString& artist,
|
||||
const QString& album, qint64 beginning, qint64 end) {
|
||||
d->valid_ = true;
|
||||
|
||||
d->title_ = title;
|
||||
|
@ -378,7 +380,7 @@ void Song::InitFromFile(const QString& filename, int directory_id) {
|
|||
if (fileref->audioProperties()) {
|
||||
d->bitrate_ = fileref->audioProperties()->bitrate();
|
||||
d->samplerate_ = fileref->audioProperties()->sampleRate();
|
||||
set_length(fileref->audioProperties()->length());
|
||||
set_length_nanosec(fileref->audioProperties()->length() * 1e9);
|
||||
}
|
||||
|
||||
// Get the filetype if we can
|
||||
|
@ -475,9 +477,10 @@ void Song::InitFromQuery(const SqlRow& q, int col) {
|
|||
|
||||
d->init_from_file_ = true;
|
||||
|
||||
#define tostr(n) (q.value(n).isNull() ? QString::null : q.value(n).toString())
|
||||
#define toint(n) (q.value(n).isNull() ? -1 : q.value(n).toInt())
|
||||
#define tofloat(n) (q.value(n).isNull() ? -1 : q.value(n).toDouble())
|
||||
#define tostr(n) (q.value(n).isNull() ? QString::null : q.value(n).toString())
|
||||
#define toint(n) (q.value(n).isNull() ? -1 : q.value(n).toInt())
|
||||
#define tolonglong(n) (q.value(n).isNull() ? -1 : q.value(n).toLongLong())
|
||||
#define tofloat(n) (q.value(n).isNull() ? -1 : q.value(n).toDouble())
|
||||
|
||||
d->id_ = toint(col + 0);
|
||||
d->title_ = tostr(col + 1);
|
||||
|
@ -523,13 +526,14 @@ void Song::InitFromQuery(const SqlRow& q, int col) {
|
|||
|
||||
// do not move those statements - beginning must be initialized before
|
||||
// length is!
|
||||
d->beginning_ = q.value(col + 32).isNull() ? 0 : q.value(col + 32).toInt();
|
||||
set_length(toint(col + 33));
|
||||
d->beginning_ = q.value(col + 32).isNull() ? 0 : q.value(col + 32).toLongLong();
|
||||
set_length_nanosec(tolonglong(col + 33));
|
||||
|
||||
d->cue_path_ = tostr(col + 34);
|
||||
|
||||
#undef tostr
|
||||
#undef toint
|
||||
#undef tolonglong
|
||||
#undef tofloat
|
||||
}
|
||||
|
||||
|
@ -543,7 +547,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
d->artist_ = track.artist();
|
||||
d->track_ = track.trackNumber();
|
||||
|
||||
set_length(track.duration());
|
||||
set_length_nanosec(track.duration() * 1e9);
|
||||
}
|
||||
#endif // HAVE_LIBLASTFM
|
||||
|
||||
|
@ -563,7 +567,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
d->genre_ = QString::fromUtf8(track->genre);
|
||||
d->comment_ = QString::fromUtf8(track->comment);
|
||||
d->compilation_ = track->compilation;
|
||||
set_length(track->tracklen / 1000);
|
||||
set_length_nanosec(track->tracklen * 1e6);
|
||||
d->bitrate_ = track->bitrate;
|
||||
d->samplerate_ = track->samplerate;
|
||||
d->mtime_ = track->time_modified;
|
||||
|
@ -593,7 +597,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
track->genre = strdup(d->genre_.toUtf8().constData());
|
||||
track->comment = strdup(d->comment_.toUtf8().constData());
|
||||
track->compilation = d->compilation_;
|
||||
track->tracklen = length() * 1000;
|
||||
track->tracklen = length_nanosec() / 1e6;
|
||||
track->bitrate = d->bitrate_;
|
||||
track->samplerate = d->samplerate_;
|
||||
track->time_modified = d->mtime_;
|
||||
|
@ -622,7 +626,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
d->basefilename_ = d->filename_;
|
||||
|
||||
d->track_ = track->tracknumber;
|
||||
set_length(track->duration / 1000);
|
||||
set_length_nanosec(track->duration * 1e6);
|
||||
d->samplerate_ = track->samplerate;
|
||||
d->bitrate_ = track->bitrate;
|
||||
d->filesize_ = track->filesize;
|
||||
|
@ -662,7 +666,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
track->filename = strdup(d->basefilename_.toUtf8().constData());
|
||||
|
||||
track->tracknumber = d->track_;
|
||||
track->duration = length() * 1000;
|
||||
track->duration = length_nanosec() / 1e6;
|
||||
track->samplerate = d->samplerate_;
|
||||
track->nochannels = 0;
|
||||
track->wavecodec = 0;
|
||||
|
@ -796,7 +800,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
d->filename_ = item_value.toString();
|
||||
|
||||
else if (wcscmp(name, g_wszWMDMDuration) == 0)
|
||||
set_length(item_value.toULongLong() / 10000000ll);
|
||||
set_length(item_value.toULongLong() * 1e2);
|
||||
|
||||
else if (wcscmp(name, L"WMDM/FileSize") == 0)
|
||||
d->filesize_ = item_value.toULongLong();
|
||||
|
@ -894,7 +898,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
AddWmdmItem(metadata, g_wszWMDMComposer, d->composer_);
|
||||
AddWmdmItem(metadata, g_wszWMDMBitrate, d->bitrate_);
|
||||
AddWmdmItem(metadata, g_wszWMDMFileName, d->basefilename_);
|
||||
AddWmdmItem(metadata, g_wszWMDMDuration, qint64(length()) * 10000000ll);
|
||||
AddWmdmItem(metadata, g_wszWMDMDuration, qint64(length_nanosec()) / 1e2);
|
||||
AddWmdmItem(metadata, L"WMDM/FileSize", d->filesize_);
|
||||
|
||||
WMDM_FORMATCODE format;
|
||||
|
@ -932,7 +936,7 @@ void Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) {
|
|||
if (!bundle.genre.isEmpty()) d->genre_ = Decode(bundle.genre, codec);
|
||||
if (!bundle.bitrate.isEmpty()) d->bitrate_ = bundle.bitrate.toInt();
|
||||
if (!bundle.samplerate.isEmpty()) d->samplerate_ = bundle.samplerate.toInt();
|
||||
if (!bundle.length.isEmpty()) set_length(bundle.length.toInt());
|
||||
if (!bundle.length.isEmpty()) set_length_nanosec(bundle.length.toLongLong());
|
||||
if (!bundle.year.isEmpty()) d->year_ = bundle.year.toInt();
|
||||
if (!bundle.tracknr.isEmpty()) d->track_ = bundle.tracknr.toInt();
|
||||
}
|
||||
|
@ -984,7 +988,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
|||
query->bindValue(":score", d->score_);
|
||||
|
||||
query->bindValue(":beginning", d->beginning_);
|
||||
query->bindValue(":length", intval(length()));
|
||||
query->bindValue(":length", intval(length_nanosec()));
|
||||
|
||||
query->bindValue(":cue_path", d->cue_path_);
|
||||
|
||||
|
@ -1009,7 +1013,7 @@ void Song::ToLastFM(lastfm::Track* track) const {
|
|||
mtrack.setArtist(d->artist_);
|
||||
mtrack.setAlbum(d->album_);
|
||||
mtrack.setTitle(d->title_);
|
||||
mtrack.setDuration(length());
|
||||
mtrack.setDuration(length_nanosec() / 1e9);
|
||||
mtrack.setTrackNumber(d->track_);
|
||||
mtrack.setSource(lastfm::Track::Player);
|
||||
}
|
||||
|
@ -1037,10 +1041,10 @@ QString Song::PrettyTitleWithArtist() const {
|
|||
}
|
||||
|
||||
QString Song::PrettyLength() const {
|
||||
if (length() == -1)
|
||||
if (length_nanosec() == -1)
|
||||
return QString::null;
|
||||
|
||||
return Utilities::PrettyTime(length());
|
||||
return Utilities::PrettyTimeNanosec(length_nanosec());
|
||||
}
|
||||
|
||||
QString Song::PrettyYear() const {
|
||||
|
@ -1076,7 +1080,7 @@ bool Song::IsMetadataEqual(const Song& other) const {
|
|||
d->comment_ == other.d->comment_ &&
|
||||
d->compilation_ == other.d->compilation_ &&
|
||||
d->beginning_ == other.d->beginning_ &&
|
||||
length() == other.length() &&
|
||||
length_nanosec() == other.length_nanosec() &&
|
||||
d->bitrate_ == other.d->bitrate_ &&
|
||||
d->samplerate_ == other.d->samplerate_ &&
|
||||
d->sampler_ == other.d->sampler_ &&
|
||||
|
@ -1177,7 +1181,7 @@ QFuture<bool> Song::BackgroundSave() const {
|
|||
bool Song::operator==(const Song& other) const {
|
||||
// TODO: this isn't working for radios
|
||||
return filename() == other.filename() &&
|
||||
beginning() == other.beginning();
|
||||
beginning_nanosec() == other.beginning_nanosec();
|
||||
}
|
||||
|
||||
QImage Song::LoadEmbeddedArt(const QString& filename) {
|
||||
|
|
|
@ -122,8 +122,8 @@ class Song {
|
|||
bool HasProperMediaFile() const;
|
||||
|
||||
// Constructors
|
||||
void Init(const QString& title, const QString& artist, const QString& album, int length);
|
||||
void Init(const QString& title, const QString& artist, const QString& album, int beginning, int end);
|
||||
void Init(const QString& title, const QString& artist, const QString& album, qint64 length);
|
||||
void Init(const QString& title, const QString& artist, const QString& album, qint64 beginning, qint64 end);
|
||||
void InitFromFile(const QString& filename, int directory_id);
|
||||
void InitFromQuery(const SqlRow& query, int col = 0);
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
|
@ -185,10 +185,10 @@ class Song {
|
|||
const QString& cue_path() const { return d->cue_path_; }
|
||||
bool has_cue() const { return !d->cue_path_.isEmpty(); }
|
||||
|
||||
int beginning() const { return d->beginning_; }
|
||||
int end() const { return d->end_; }
|
||||
qint64 beginning_nanosec() const { return d->beginning_; }
|
||||
qint64 end_nanosec() const { return d->end_; }
|
||||
|
||||
int length() const { return d->end_ - d->beginning_; }
|
||||
qint64 length_nanosec() const { return d->end_ - d->beginning_; }
|
||||
|
||||
int bitrate() const { return d->bitrate_; }
|
||||
int samplerate() const { return d->samplerate_; }
|
||||
|
@ -248,9 +248,9 @@ class Song {
|
|||
void set_comment(const QString& v) { d->comment_ = v; }
|
||||
void set_compilation(bool v) { d->compilation_ = v; }
|
||||
void set_sampler(bool v) { d->sampler_ = v; }
|
||||
void set_beginning(int v) { d->beginning_ = qMax(0, v); }
|
||||
void set_end(int v) { d->end_ = v; }
|
||||
void set_length(int v) { d->end_ = d->beginning_ + v; }
|
||||
void set_beginning_nanosec(qint64 v) { d->beginning_ = qMax(0ll, v); }
|
||||
void set_end_nanosec(qint64 v) { d->end_ = v; }
|
||||
void set_length_nanosec(qint64 v) { d->end_ = d->beginning_ + v; }
|
||||
void set_bitrate(int v) { d->bitrate_ = v; }
|
||||
void set_samplerate(int v) { d->samplerate_ = v; }
|
||||
void set_mtime(int v) { d->mtime_ = v; }
|
||||
|
@ -321,14 +321,14 @@ class Song {
|
|||
// streams, this will equal to 0. In case of multi-part streams on the
|
||||
// other hand, this will mark the beginning of a section represented by
|
||||
// this Song object. This is always greater than 0.
|
||||
int beginning_;
|
||||
qint64 beginning_;
|
||||
// The end of the song in seconds. In case of single-part media
|
||||
// streams, this will equal to the song's length. In case of multi-part
|
||||
// streams on the other hand, this will mark the end of a section
|
||||
// represented by this Song object.
|
||||
// This may be negative indicating that the length of this song is
|
||||
// unknown.
|
||||
int end_;
|
||||
qint64 end_;
|
||||
|
||||
int bitrate_;
|
||||
int samplerate_;
|
||||
|
|
|
@ -62,6 +62,10 @@ QString PrettyTime(int seconds) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
QString PrettyTimeNanosec(qint64 nanoseconds) {
|
||||
return PrettyTime(nanoseconds / 1e9);
|
||||
}
|
||||
|
||||
QString WordyTime(quint64 seconds) {
|
||||
quint64 days = seconds / (60*60*24);
|
||||
|
||||
|
@ -75,6 +79,10 @@ QString WordyTime(quint64 seconds) {
|
|||
return parts.join(" ");
|
||||
}
|
||||
|
||||
QString WordyTimeNanosec(qint64 nanoseconds) {
|
||||
return WordyTime(nanoseconds / 1e9);
|
||||
}
|
||||
|
||||
QString Ago(int seconds_since_epoch, const QLocale& locale) {
|
||||
const QDateTime now = QDateTime::currentDateTime();
|
||||
const QDateTime then = QDateTime::fromTime_t(seconds_since_epoch);
|
||||
|
|
|
@ -28,8 +28,10 @@ class QIODevice;
|
|||
|
||||
namespace Utilities {
|
||||
QString PrettyTime(int seconds);
|
||||
QString PrettyTimeNanosec(qint64 nanoseconds);
|
||||
QString PrettySize(quint64 bytes);
|
||||
QString WordyTime(quint64 seconds);
|
||||
QString WordyTimeNanosec(qint64 nanoseconds);
|
||||
QString Ago(int seconds_since_epoch, const QLocale& locale);
|
||||
|
||||
QString ColorToRgba(const QColor& color);
|
||||
|
|
|
@ -561,7 +561,7 @@ SongList LibraryBackend::GetSongsById(const QStringList& ids, QSqlDatabase& db)
|
|||
return ret;
|
||||
}
|
||||
|
||||
Song LibraryBackend::GetSongByFilename(const QString& filename, int beginning) {
|
||||
Song LibraryBackend::GetSongByFilename(const QString& filename, qint64 beginning) {
|
||||
LibraryQuery query;
|
||||
query.SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
|
||||
query.AddWhere("filename", filename);
|
||||
|
|
|
@ -88,7 +88,7 @@ class LibraryBackendInterface : public QObject {
|
|||
// Returns a section of a song with the given filename and beginning. If the section
|
||||
// is not present in library, returns invalid song.
|
||||
// Using default beginning value is suitable when searching for single-section songs.
|
||||
virtual Song GetSongByFilename(const QString& filename, int beginning = 0) = 0;
|
||||
virtual Song GetSongByFilename(const QString& filename, qint64 beginning = 0) = 0;
|
||||
|
||||
virtual void AddDirectory(const QString& path) = 0;
|
||||
virtual void RemoveDirectory(const Directory& dir) = 0;
|
||||
|
@ -144,7 +144,7 @@ class LibraryBackend : public LibraryBackendInterface {
|
|||
const QString& column);
|
||||
|
||||
SongList GetSongsByFilename(const QString& filename);
|
||||
Song GetSongByFilename(const QString& filename, int beginning = 0);
|
||||
Song GetSongByFilename(const QString& filename, qint64 beginning = 0);
|
||||
|
||||
void AddDirectory(const QString& path);
|
||||
void RemoveDirectory(const Directory& dir);
|
||||
|
|
|
@ -397,9 +397,9 @@ void LibraryWatcher::UpdateCueAssociatedSongs(const QString& file, const QString
|
|||
|
||||
SongList old_sections = backend_->GetSongsByFilename(file);
|
||||
|
||||
QHash<int, Song> sections_map;
|
||||
QHash<quint64, Song> sections_map;
|
||||
foreach(const Song& song, old_sections) {
|
||||
sections_map[song.beginning()] = song;
|
||||
sections_map[song.beginning_nanosec()] = song;
|
||||
}
|
||||
|
||||
QSet<int> used_ids;
|
||||
|
@ -408,7 +408,7 @@ void LibraryWatcher::UpdateCueAssociatedSongs(const QString& file, const QString
|
|||
foreach(Song cue_song, cue_parser_->Load(&cue, matching_cue, path)) {
|
||||
cue_song.set_directory_id(t->dir());
|
||||
|
||||
Song matching = sections_map[cue_song.beginning()];
|
||||
Song matching = sections_map[cue_song.beginning_nanosec()];
|
||||
// a new section
|
||||
if(!matching.is_valid()) {
|
||||
t->new_songs << cue_song;
|
||||
|
|
|
@ -244,7 +244,7 @@ QVariant Playlist::data(const QModelIndex& index, int role) const {
|
|||
return song.filename();
|
||||
case Column_Artist: return song.artist();
|
||||
case Column_Album: return song.album();
|
||||
case Column_Length: return song.length();
|
||||
case Column_Length: return song.length_nanosec();
|
||||
case Column_Track: return song.track();
|
||||
case Column_Disc: return song.disc();
|
||||
case Column_Year: return song.year();
|
||||
|
@ -960,7 +960,7 @@ bool Playlist::CompareItems(int column, Qt::SortOrder order,
|
|||
case Column_Title: strcmp(title);
|
||||
case Column_Artist: strcmp(artist);
|
||||
case Column_Album: strcmp(album);
|
||||
case Column_Length: cmp(length);
|
||||
case Column_Length: cmp(length_nanosec);
|
||||
case Column_Track: cmp(track);
|
||||
case Column_Disc: cmp(disc);
|
||||
case Column_Year: cmp(year);
|
||||
|
@ -1285,7 +1285,7 @@ Song Playlist::current_item_metadata() const {
|
|||
}
|
||||
|
||||
void Playlist::UpdateScrobblePoint() {
|
||||
const int length = current_item_metadata().length();
|
||||
const int length = current_item_metadata().length_nanosec();
|
||||
|
||||
scrobble_point_ = length == 0 ? 240 : qBound(31, length/2, 240);
|
||||
has_scrobbled_ = false;
|
||||
|
@ -1447,7 +1447,7 @@ SongList Playlist::GetAllSongs() const {
|
|||
quint64 Playlist::GetTotalLength() const {
|
||||
quint64 ret = 0;
|
||||
foreach (PlaylistItemPtr item, items_) {
|
||||
int length = item->Metadata().length();
|
||||
quint64 length = item->Metadata().length_nanosec();
|
||||
if (length > 0)
|
||||
ret += length;
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, boost::sha
|
|||
|
||||
foreach(const Song& from_list, song_list) {
|
||||
if(from_list.filename() == song.filename() &&
|
||||
from_list.beginning() == song.beginning()) {
|
||||
from_list.beginning_nanosec() == song.beginning_nanosec()) {
|
||||
// we found a matching section; replace the input
|
||||
// item with a new one containing CUE metadata
|
||||
return PlaylistItemPtr(new SongPlaylistItem(from_list));
|
||||
|
|
|
@ -259,10 +259,10 @@ bool PlaylistDelegateBase::helpEvent(QHelpEvent *event, QAbstractItemView *view,
|
|||
|
||||
QString LengthItemDelegate::displayText(const QVariant& value, const QLocale&) const {
|
||||
bool ok = false;
|
||||
int seconds = value.toInt(&ok);
|
||||
qint64 nanoseconds = value.toLongLong(&ok);
|
||||
|
||||
if (ok && seconds > 0)
|
||||
return Utilities::PrettyTime(seconds);
|
||||
if (ok && nanoseconds > 0)
|
||||
return Utilities::PrettyTimeNanosec(nanoseconds);
|
||||
return QString::null;
|
||||
}
|
||||
|
||||
|
|
|
@ -264,7 +264,7 @@ void PlaylistManager::ChangePlaylistOrder(const QList<int>& ids) {
|
|||
|
||||
void PlaylistManager::UpdateSummaryText() {
|
||||
int tracks = current()->rowCount();
|
||||
quint64 seconds = 0;
|
||||
quint64 nanoseconds = 0;
|
||||
int selected = 0;
|
||||
|
||||
// Get the length of the selected tracks
|
||||
|
@ -274,9 +274,9 @@ void PlaylistManager::UpdateSummaryText() {
|
|||
|
||||
selected += range.bottom() - range.top() + 1;
|
||||
for (int i=range.top() ; i<=range.bottom() ; ++i) {
|
||||
int length = range.model()->index(i, Playlist::Column_Length).data().toInt();
|
||||
int length = range.model()->index(i, Playlist::Column_Length).data().toLongLong();
|
||||
if (length > 0)
|
||||
seconds += length;
|
||||
nanoseconds += length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,14 +284,14 @@ void PlaylistManager::UpdateSummaryText() {
|
|||
if (selected > 1) {
|
||||
summary += tr("%1 selected of").arg(selected) + " ";
|
||||
} else {
|
||||
seconds = current()->GetTotalLength();
|
||||
nanoseconds = current()->GetTotalLength();
|
||||
}
|
||||
|
||||
// TODO: Make the plurals translatable
|
||||
summary += tracks == 1 ? tr("1 track") : tr("%1 tracks").arg(tracks);
|
||||
|
||||
if (seconds)
|
||||
summary += " - [ " + Utilities::WordyTime(seconds) + " ]";
|
||||
if (nanoseconds)
|
||||
summary += " - [ " + Utilities::WordyTimeNanosec(nanoseconds) + " ]";
|
||||
|
||||
emit SummaryTextChanged(summary);
|
||||
}
|
||||
|
|
|
@ -53,10 +53,10 @@ bool SongPlaylistItem::InitFromQuery(const SqlRow& query) {
|
|||
} else {
|
||||
song_.InitFromFile(filename, -1);
|
||||
|
||||
int beginning(query.value(row + 7).toInt());
|
||||
qint64 beginning(query.value(row + 7).toInt());
|
||||
QString cue_path(query.value(row + 8).toString());
|
||||
|
||||
song_.set_beginning(beginning);
|
||||
song_.set_beginning_nanosec(beginning);
|
||||
song_.set_cue_path(cue_path);
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,8 @@ QVariant SongPlaylistItem::DatabaseValue(DatabaseColumn column) const {
|
|||
case Column_Title: return song_.title();
|
||||
case Column_Artist: return song_.artist();
|
||||
case Column_Album: return song_.album();
|
||||
case Column_Length: return song_.length();
|
||||
case Column_Beginning: return song_.beginning();
|
||||
case Column_Length: return song_.length_nanosec();
|
||||
case Column_Beginning: return song_.beginning_nanosec();
|
||||
case Column_CuePath: return song_.cue_path();
|
||||
default: return PlaylistItem::DatabaseValue(column);
|
||||
}
|
||||
|
|
|
@ -266,8 +266,8 @@ QStringList CueParser::SplitCueLine(const QString& line) const {
|
|||
// Updates the song with data from the .cue entry. This one mustn't be used for the
|
||||
// last song in the .cue file.
|
||||
bool CueParser::UpdateSong(const CueEntry& entry, const QString& next_index, Song* song) const {
|
||||
int beginning = IndexToMarker(entry.index);
|
||||
int end = IndexToMarker(next_index);
|
||||
qint64 beginning = IndexToMarker(entry.index);
|
||||
qint64 end = IndexToMarker(next_index);
|
||||
|
||||
// incorrect indices (we won't be able to calculate beginning or end)
|
||||
if(beginning == -1 || end == -1) {
|
||||
|
@ -286,7 +286,7 @@ bool CueParser::UpdateSong(const CueEntry& entry, const QString& next_index, Son
|
|||
// Updates the song with data from the .cue entry. This one must be used only for the
|
||||
// last song in the .cue file.
|
||||
bool CueParser::UpdateLastSong(const CueEntry& entry, Song* song) const {
|
||||
int beginning = IndexToMarker(entry.index);
|
||||
qint64 beginning = IndexToMarker(entry.index);
|
||||
|
||||
// incorrect index (we won't be able to calculate beginning)
|
||||
if(beginning == -1) {
|
||||
|
@ -304,12 +304,12 @@ bool CueParser::UpdateLastSong(const CueEntry& entry, Song* song) const {
|
|||
|
||||
// we don't do anything with the end here because it's already set to
|
||||
// the end of the media file (if it exists)
|
||||
song->set_beginning(beginning);
|
||||
song->set_beginning_nanosec(beginning);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CueParser::IndexToMarker(const QString& index) const {
|
||||
qint64 CueParser::IndexToMarker(const QString& index) const {
|
||||
QRegExp index_regexp(kIndexRegExp);
|
||||
if(!index_regexp.exactMatch(index)) {
|
||||
return -1;
|
||||
|
@ -317,7 +317,7 @@ int CueParser::IndexToMarker(const QString& index) const {
|
|||
|
||||
QStringList splitted = index_regexp.capturedTexts().mid(1, -1);
|
||||
// TODO: use frames when #1166 is fixed
|
||||
return splitted.at(0).toInt() * 60 + splitted.at(1).toInt();
|
||||
return splitted.at(0).toLongLong() * 60 + splitted.at(1).toLongLong();
|
||||
}
|
||||
|
||||
void CueParser::Save(const SongList &songs, QIODevice *device, const QDir &dir) const {
|
||||
|
|
|
@ -86,7 +86,7 @@ class CueParser : public ParserBase {
|
|||
bool UpdateLastSong(const CueEntry& entry, Song* song) const;
|
||||
|
||||
QStringList SplitCueLine(const QString& line) const;
|
||||
int IndexToMarker(const QString& index) const;
|
||||
qint64 IndexToMarker(const QString& index) const;
|
||||
};
|
||||
|
||||
#endif // CUEPARSER_H
|
||||
|
|
|
@ -119,7 +119,9 @@ void M3UParser::Save(const SongList &songs, QIODevice *device, const QDir &dir)
|
|||
if (song.filename().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QString meta = QString("#EXTINF:%1,%2 - %3\n").arg(song.length()).arg(song.artist()).arg(song.title());
|
||||
QString meta = QString("#EXTINF:%1,%2 - %3\n")
|
||||
.arg(song.length_nanosec())
|
||||
.arg(song.artist()).arg(song.title());
|
||||
device->write(meta.toUtf8());
|
||||
device->write(MakeRelativeTo(song.filename(), dir).toUtf8());
|
||||
device->write("\n");
|
||||
|
|
|
@ -79,7 +79,7 @@ QString ParserBase::MakeUrl(const QString& filename_or_url) const {
|
|||
return QUrl::fromLocalFile(filename_or_url).toString();
|
||||
}
|
||||
|
||||
Song ParserBase::LoadLibrarySong(const QString& filename_or_url, int beginning) const {
|
||||
Song ParserBase::LoadLibrarySong(const QString& filename_or_url, qint64 beginning) const {
|
||||
if (!library_)
|
||||
return Song();
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ protected:
|
|||
// Converts the URL or path to a canonical path and searches the library for
|
||||
// a section of a song with that path and the given beginning. If one is found,
|
||||
// returns it, otherwise returns an invalid song.
|
||||
Song LoadLibrarySong(const QString& filename_or_url, int beginning = 0) const;
|
||||
Song LoadLibrarySong(const QString& filename_or_url, qint64 beginning = 0) const;
|
||||
|
||||
private:
|
||||
LibraryBackendInterface* library_;
|
||||
|
|
|
@ -52,7 +52,7 @@ SongList PLSParser::Load(QIODevice *device, const QString& playlist_path, const
|
|||
} else if (key.startsWith("title")) {
|
||||
songs[n].set_title(value);
|
||||
} else if (key.startsWith("length")) {
|
||||
songs[n].set_length(value.toInt());
|
||||
songs[n].set_length_nanosec(value.toLongLong() * 1e9);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ void PLSParser::Save(const SongList &songs, QIODevice *device, const QDir &dir)
|
|||
foreach (const Song& song, songs) {
|
||||
s << "File" << n << "=" << MakeRelativeTo(song.filename(), dir) << endl;
|
||||
s << "Title" << n << "=" << song.title() << endl;
|
||||
s << "Length" << n << "=" << song.length() << endl;
|
||||
s << "Length" << n << "=" << song.length_nanosec() / 1e9 << endl;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,8 +128,8 @@ void XSPFParser::Save(const SongList& songs, QIODevice* device, const QDir&) con
|
|||
if (!song.album().isEmpty()) {
|
||||
writer.writeTextElement("album", song.album());
|
||||
}
|
||||
if (song.length() != -1) {
|
||||
writer.writeTextElement("duration", QString::number(song.length() * 1000));
|
||||
if (song.length_nanosec() != -1) {
|
||||
writer.writeTextElement("duration", QString::number(song.length_nanosec() / 1e6));
|
||||
}
|
||||
|
||||
QString art = song.art_manual().isEmpty() ? song.art_automatic() : song.art_manual();
|
||||
|
|
|
@ -335,7 +335,7 @@ Song JamendoService::ReadTrack(const QString& artist,
|
|||
song.set_title(reader->readElementText().trimmed());
|
||||
} else if (name == "duration") {
|
||||
const int length = reader->readElementText().toFloat();
|
||||
song.set_length(length);
|
||||
song.set_length_nanosec(length * 1e9);
|
||||
} else if (name == "id3genre") {
|
||||
int genre_id = reader->readElementText().toInt();
|
||||
// In theory, genre 0 is "blues"; in practice it's invalid.
|
||||
|
|
|
@ -203,7 +203,7 @@ Song MagnatuneService::ReadTrack(QXmlStreamReader& reader) {
|
|||
if (name == "tracknum") song.set_track(value.toInt());
|
||||
if (name == "year") song.set_year(value.toInt());
|
||||
if (name == "magnatunegenres") song.set_genre(value.section(',', 0, 0));
|
||||
if (name == "seconds") song.set_length(value.toInt());
|
||||
if (name == "seconds") song.set_length_nanosec(value.toInt() * 1e9);
|
||||
if (name == "url") song.set_filename(value);
|
||||
if (name == "cover_small") song.set_art_automatic(value);
|
||||
if (name == "albumsku") song.set_comment(value);
|
||||
|
|
|
@ -58,10 +58,10 @@ public:
|
|||
const QString& cue_path() const;
|
||||
bool has_cue() const;
|
||||
|
||||
int beginning() const;
|
||||
int end() const;
|
||||
int beginning_nanosec() const;
|
||||
int end_nanosec() const;
|
||||
|
||||
int length() const;
|
||||
int length_nanosec() const;
|
||||
|
||||
int bitrate() const;
|
||||
int samplerate() const;
|
||||
|
@ -115,9 +115,9 @@ public:
|
|||
void set_comment(const QString& v);
|
||||
void set_compilation(bool v);
|
||||
void set_sampler(bool v);
|
||||
void set_beginning(int v);
|
||||
void set_end(int v);
|
||||
void set_length(int v);
|
||||
void set_beginning_nanosec(int v);
|
||||
void set_end_nanosec(int v);
|
||||
void set_length_nanosec(int v);
|
||||
void set_bitrate(int v);
|
||||
void set_samplerate(int v);
|
||||
void set_mtime(int v);
|
||||
|
|
|
@ -430,7 +430,7 @@ void EditTagDialog::UpdateSummaryTab(const Song& song) {
|
|||
album_cover_choice_controller_->show_cover_action()->setEnabled(art_is_set);
|
||||
ui_->summary_art_button->setEnabled(song.id() != -1);
|
||||
|
||||
ui_->length->setText(Utilities::PrettyTime(song.length()));
|
||||
ui_->length->setText(Utilities::PrettyTimeNanosec(song.length_nanosec()));
|
||||
SetText(ui_->bpm, song.bpm(), tr("bpm"));
|
||||
SetText(ui_->samplerate, song.samplerate(), "Hz");
|
||||
SetText(ui_->bitrate, song.bitrate(), tr("kbps"));
|
||||
|
|
|
@ -927,7 +927,7 @@ void MainWindow::UpdateTrackPosition() {
|
|||
PlaylistItemPtr item(player_->GetCurrentItem());
|
||||
const int position = std::floor(
|
||||
float(player_->engine()->position_nanosec()) / 1e9 + 0.5);
|
||||
const int length = item->Metadata().length();
|
||||
const int length = item->Metadata().length_nanosec() / 1e9;
|
||||
|
||||
if (length <= 0) {
|
||||
// Probably a stream that we don't know the length of
|
||||
|
|
Loading…
Reference in New Issue