aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/decoder/plugins/AdPlugDecoderPlugin.cxx2
-rw-r--r--src/decoder/plugins/AudiofileDecoderPlugin.cxx14
-rw-r--r--src/decoder/plugins/DsdiffDecoderPlugin.cxx5
-rw-r--r--src/decoder/plugins/DsfDecoderPlugin.cxx6
-rw-r--r--src/decoder/plugins/FaadDecoderPlugin.cxx8
-rw-r--r--src/decoder/plugins/FfmpegDecoderPlugin.cxx9
-rw-r--r--src/decoder/plugins/FlacMetadata.cxx10
-rw-r--r--src/decoder/plugins/FlacMetadata.hxx9
-rw-r--r--src/decoder/plugins/GmeDecoderPlugin.cxx2
-rw-r--r--src/decoder/plugins/MadDecoderPlugin.cxx8
-rw-r--r--src/decoder/plugins/ModplugDecoderPlugin.cxx2
-rw-r--r--src/decoder/plugins/Mp4v2DecoderPlugin.cxx6
-rw-r--r--src/decoder/plugins/MpcdecDecoderPlugin.cxx13
-rw-r--r--src/decoder/plugins/Mpg123DecoderPlugin.cxx7
-rw-r--r--src/decoder/plugins/OpusDecoderPlugin.cxx9
-rw-r--r--src/decoder/plugins/SidplayDecoderPlugin.cxx2
-rw-r--r--src/decoder/plugins/SndfileDecoderPlugin.cxx5
-rw-r--r--src/decoder/plugins/VorbisDecoderPlugin.cxx6
-rw-r--r--src/decoder/plugins/WavpackDecoderPlugin.cxx7
-rw-r--r--src/decoder/plugins/WildmidiDecoderPlugin.cxx4
-rw-r--r--src/tag/TagHandler.cxx4
-rw-r--r--src/tag/TagHandler.hxx9
-rw-r--r--test/read_tags.cxx4
23 files changed, 83 insertions, 68 deletions
diff --git a/src/decoder/plugins/AdPlugDecoderPlugin.cxx b/src/decoder/plugins/AdPlugDecoderPlugin.cxx
index 6c8edfe02..2d7ce696e 100644
--- a/src/decoder/plugins/AdPlugDecoderPlugin.cxx
+++ b/src/decoder/plugins/AdPlugDecoderPlugin.cxx
@@ -102,7 +102,7 @@ adplug_scan_file(Path path_fs,
return false;
tag_handler_invoke_duration(handler, handler_ctx,
- player->songlength() / 1000);
+ SongTime::FromMS(player->songlength()));
if (handler->tag != nullptr) {
adplug_scan_tag(TAG_TITLE, player->gettitle(),
diff --git a/src/decoder/plugins/AudiofileDecoderPlugin.cxx b/src/decoder/plugins/AudiofileDecoderPlugin.cxx
index 8d04f9596..0e34a20ff 100644
--- a/src/decoder/plugins/AudiofileDecoderPlugin.cxx
+++ b/src/decoder/plugins/AudiofileDecoderPlugin.cxx
@@ -244,19 +244,19 @@ audiofile_stream_decode(Decoder &decoder, InputStream &is)
}
gcc_pure
-static int
+static SignedSongTime
audiofile_get_duration(InputStream &is)
{
if (!is.IsSeekable() || !is.KnownSize())
- return -1;
+ return SignedSongTime::Negative();
AudioFileInputStream afis{nullptr, is};
AFvirtualfile *vf = setup_virtual_fops(afis);
AFfilehandle fh = afOpenVirtualFile(vf, "r", nullptr);
if (fh == AF_NULL_FILEHANDLE)
- return -1;
+ return SignedSongTime::Negative();
- int duration = audiofile_get_duration(fh).RoundS();
+ const auto duration = audiofile_get_duration(fh);
afCloseFile(fh);
return duration;
}
@@ -265,11 +265,11 @@ static bool
audiofile_scan_stream(InputStream &is,
const struct tag_handler *handler, void *handler_ctx)
{
- int total_time = audiofile_get_duration(is);
- if (total_time < 0)
+ const auto duration = audiofile_get_duration(is);
+ if (duration.IsNegative())
return false;
- tag_handler_invoke_duration(handler, handler_ctx, total_time);
+ tag_handler_invoke_duration(handler, handler_ctx, SongTime(duration));
return true;
}
diff --git a/src/decoder/plugins/DsdiffDecoderPlugin.cxx b/src/decoder/plugins/DsdiffDecoderPlugin.cxx
index 617d34ae4..b6c79e11e 100644
--- a/src/decoder/plugins/DsdiffDecoderPlugin.cxx
+++ b/src/decoder/plugins/DsdiffDecoderPlugin.cxx
@@ -474,8 +474,9 @@ dsdiff_scan_stream(InputStream &is,
return false;
/* calculate song time and add as tag */
- unsigned songtime = ((metadata.chunk_size / metadata.channels) * 8) /
- metadata.sample_rate;
+ uint64_t n_frames = metadata.chunk_size / audio_format.channels;
+ auto songtime = SongTime::FromScale<uint64_t>(n_frames,
+ audio_format.sample_rate);
tag_handler_invoke_duration(handler, handler_ctx, songtime);
/* Read additional metadata and created tags if available */
diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx
index b84eadf66..690616d15 100644
--- a/src/decoder/plugins/DsfDecoderPlugin.cxx
+++ b/src/decoder/plugins/DsfDecoderPlugin.cxx
@@ -42,7 +42,6 @@
#include <string.h>
static constexpr unsigned DSF_BLOCK_SIZE = 4096;
-static constexpr unsigned DSF_BLOCK_BITS = DSF_BLOCK_SIZE * 8;
struct DsfMetaData {
unsigned sample_rate, channels;
@@ -348,8 +347,9 @@ dsf_scan_stream(InputStream &is,
return false;
/* calculate song time and add as tag */
- unsigned songtime = (metadata.n_blocks * DSF_BLOCK_BITS) /
- metadata.sample_rate;
+ const auto n_blocks = metadata.n_blocks;
+ auto songtime = SongTime::FromScale<uint64_t>(n_blocks * DSF_BLOCK_SIZE,
+ audio_format.sample_rate);
tag_handler_invoke_duration(handler, handler_ctx, songtime);
#ifdef HAVE_ID3TAG
diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx
index 5b352c9f4..d59309a3a 100644
--- a/src/decoder/plugins/FaadDecoderPlugin.cxx
+++ b/src/decoder/plugins/FaadDecoderPlugin.cxx
@@ -438,11 +438,9 @@ faad_scan_stream(InputStream &is,
if (!result.first)
return false;
- unsigned duration = result.second.IsNegative()
- ? 0
- : result.second.RoundS();
-
- tag_handler_invoke_duration(handler, handler_ctx, duration);
+ if (!result.second.IsNegative())
+ tag_handler_invoke_duration(handler, handler_ctx,
+ SongTime(result.second));
return true;
}
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
index 0693ffd43..7f4ac8bcc 100644
--- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
@@ -609,9 +609,12 @@ ffmpeg_scan_stream(InputStream &is,
return false;
}
- if (f->duration != (int64_t)AV_NOPTS_VALUE)
- tag_handler_invoke_duration(handler, handler_ctx,
- f->duration / AV_TIME_BASE);
+ if (f->duration != (int64_t)AV_NOPTS_VALUE) {
+ const auto duration =
+ SongTime::FromScale<uint64_t>(f->duration,
+ AV_TIME_BASE);
+ tag_handler_invoke_duration(handler, handler_ctx, duration);
+ }
ffmpeg_scan_dictionary(f->metadata, handler, handler_ctx);
int idx = ffmpeg_find_audio_stream(f);
diff --git a/src/decoder/plugins/FlacMetadata.cxx b/src/decoder/plugins/FlacMetadata.cxx
index b921e8481..0ee6026dd 100644
--- a/src/decoder/plugins/FlacMetadata.cxx
+++ b/src/decoder/plugins/FlacMetadata.cxx
@@ -179,6 +179,16 @@ flac_scan_comments(const FLAC__StreamMetadata_VorbisComment *comment,
handler, handler_ctx);
}
+gcc_pure
+static inline SongTime
+flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
+{
+ assert(stream_info->sample_rate > 0);
+
+ return SongTime::FromScale<uint64_t>(stream_info->total_samples,
+ stream_info->sample_rate);
+}
+
void
flac_scan_metadata(const FLAC__StreamMetadata *block,
const struct tag_handler *handler, void *handler_ctx)
diff --git a/src/decoder/plugins/FlacMetadata.hxx b/src/decoder/plugins/FlacMetadata.hxx
index e0449b2a2..16af8bd02 100644
--- a/src/decoder/plugins/FlacMetadata.hxx
+++ b/src/decoder/plugins/FlacMetadata.hxx
@@ -114,15 +114,6 @@ public:
struct Tag;
struct ReplayGainInfo;
-static inline unsigned
-flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
-{
- assert(stream_info->sample_rate > 0);
-
- return (stream_info->total_samples + stream_info->sample_rate - 1) /
- stream_info->sample_rate;
-}
-
bool
flac_parse_replay_gain(ReplayGainInfo &rgi,
const FLAC__StreamMetadata *block);
diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx
index e1b281f93..cc6ce5e5d 100644
--- a/src/decoder/plugins/GmeDecoderPlugin.cxx
+++ b/src/decoder/plugins/GmeDecoderPlugin.cxx
@@ -238,7 +238,7 @@ gme_scan_file(Path path_fs,
if (ti->length > 0)
tag_handler_invoke_duration(handler, handler_ctx,
- ti->length / 100);
+ SongTime::FromMS(ti->length));
if (ti->song != nullptr) {
if (gme_track_count(emu) > 1) {
diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx
index 3175d4bf6..8c9707b89 100644
--- a/src/decoder/plugins/MadDecoderPlugin.cxx
+++ b/src/decoder/plugins/MadDecoderPlugin.cxx
@@ -1094,11 +1094,9 @@ mad_decoder_scan_stream(InputStream &is,
if (!result.first)
return false;
- unsigned duration = result.second.IsNegative()
- ? 0
- : result.second.RoundS();
-
- tag_handler_invoke_duration(handler, handler_ctx, duration);
+ if (!result.second.IsNegative())
+ tag_handler_invoke_duration(handler, handler_ctx,
+ SongTime(result.second));
return true;
}
diff --git a/src/decoder/plugins/ModplugDecoderPlugin.cxx b/src/decoder/plugins/ModplugDecoderPlugin.cxx
index 279790b93..3e0a41550 100644
--- a/src/decoder/plugins/ModplugDecoderPlugin.cxx
+++ b/src/decoder/plugins/ModplugDecoderPlugin.cxx
@@ -184,7 +184,7 @@ modplug_scan_stream(InputStream &is,
return false;
tag_handler_invoke_duration(handler, handler_ctx,
- ModPlug_GetLength(f) / 1000);
+ SongTime::FromMS(ModPlug_GetLength(f)));
const char *title = ModPlug_GetName(f);
if (title != nullptr)
diff --git a/src/decoder/plugins/Mp4v2DecoderPlugin.cxx b/src/decoder/plugins/Mp4v2DecoderPlugin.cxx
index d59be7f09..d4f7c5843 100644
--- a/src/decoder/plugins/Mp4v2DecoderPlugin.cxx
+++ b/src/decoder/plugins/Mp4v2DecoderPlugin.cxx
@@ -256,8 +256,10 @@ mp4_scan_file(Path path_fs,
return false;
}
- const MP4Duration dur = MP4GetTrackDuration(handle, id) /
- MP4GetTrackTimeScale(handle, id);
+ const MP4Timestamp scale = MP4GetTrackTimeScale(handle, id);
+ const SongTime dur =
+ SongTime::FromScale<uint64_t>(MP4GetTrackDuration(handle, id),
+ scale);
tag_handler_invoke_duration(handler, handler_ctx, dur);
const MP4Tags* tags = MP4TagsAlloc();
diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx
index 08e060bee..befed0f3b 100644
--- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx
+++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx
@@ -228,7 +228,7 @@ mpcdec_decode(Decoder &mpd_decoder, InputStream &is)
mpc_demux_exit(demux);
}
-static float
+static SignedSongTime
mpcdec_get_file_duration(InputStream &is)
{
mpc_decoder_data data(is, nullptr);
@@ -243,25 +243,24 @@ mpcdec_get_file_duration(InputStream &is)
mpc_demux *demux = mpc_demux_init(&reader);
if (demux == nullptr)
- return -1;
+ return SignedSongTime::Negative();
mpc_streaminfo info;
mpc_demux_get_info(demux, &info);
mpc_demux_exit(demux);
- return mpc_streaminfo_get_length(&info);
+ return SongTime::FromS(mpc_streaminfo_get_length(&info));
}
static bool
mpcdec_scan_stream(InputStream &is,
const struct tag_handler *handler, void *handler_ctx)
{
- float total_time = mpcdec_get_file_duration(is);
-
- if (total_time < 0)
+ const auto duration = mpcdec_get_file_duration(is);
+ if (duration.IsNegative())
return false;
- tag_handler_invoke_duration(handler, handler_ctx, total_time);
+ tag_handler_invoke_duration(handler, handler_ctx, SongTime(duration));
return true;
}
diff --git a/src/decoder/plugins/Mpg123DecoderPlugin.cxx b/src/decoder/plugins/Mpg123DecoderPlugin.cxx
index 798cc953d..013155bf5 100644
--- a/src/decoder/plugins/Mpg123DecoderPlugin.cxx
+++ b/src/decoder/plugins/Mpg123DecoderPlugin.cxx
@@ -233,8 +233,11 @@ mpd_mpg123_scan_file(Path path_fs,
mpg123_delete(handle);
- tag_handler_invoke_duration(handler, handler_ctx,
- num_samples / audio_format.sample_rate);
+ const auto duration =
+ SongTime::FromScale<uint64_t>(num_samples,
+ audio_format.sample_rate);
+
+ tag_handler_invoke_duration(handler, handler_ctx, duration);
return true;
}
diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx
index 2de827c7f..97c81984c 100644
--- a/src/decoder/plugins/OpusDecoderPlugin.cxx
+++ b/src/decoder/plugins/OpusDecoderPlugin.cxx
@@ -441,9 +441,12 @@ mpd_opus_scan_stream(InputStream &is,
}
}
- if (packet.e_o_s || OggSeekFindEOS(oy, os, packet, is))
- tag_handler_invoke_duration(handler, handler_ctx,
- packet.granulepos / opus_sample_rate);
+ if (packet.e_o_s || OggSeekFindEOS(oy, os, packet, is)) {
+ const auto duration =
+ SongTime::FromScale<uint64_t>(packet.granulepos,
+ opus_sample_rate);
+ tag_handler_invoke_duration(handler, handler_ctx, duration);
+ }
ogg_stream_clear(&os);
diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx
index 2adfa6df9..8435f095f 100644
--- a/src/decoder/plugins/SidplayDecoderPlugin.cxx
+++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx
@@ -388,7 +388,7 @@ sidplay_scan_file(Path path_fs,
const auto duration = get_song_length(path_fs);
if (!duration.IsNegative())
tag_handler_invoke_duration(handler, handler_ctx,
- duration.RoundS());
+ SongTime(duration));
return true;
}
diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx
index 78897da58..558101089 100644
--- a/src/decoder/plugins/SndfileDecoderPlugin.cxx
+++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx
@@ -246,8 +246,9 @@ sndfile_scan_stream(InputStream &is,
return false;
}
- tag_handler_invoke_duration(handler, handler_ctx,
- info.frames / info.samplerate);
+ const auto duration =
+ SongTime::FromScale<uint64_t>(info.frames, info.samplerate);
+ tag_handler_invoke_duration(handler, handler_ctx, duration);
for (auto i : sndfile_tags)
sndfile_handle_tag(sf, i.str, i.tag, handler, handler_ctx);
diff --git a/src/decoder/plugins/VorbisDecoderPlugin.cxx b/src/decoder/plugins/VorbisDecoderPlugin.cxx
index 8348407d6..e0d3d1374 100644
--- a/src/decoder/plugins/VorbisDecoderPlugin.cxx
+++ b/src/decoder/plugins/VorbisDecoderPlugin.cxx
@@ -347,8 +347,10 @@ vorbis_scan_stream(InputStream &is,
if (!vorbis_is_open(&vis, &vf))
return false;
- tag_handler_invoke_duration(handler, handler_ctx,
- (int)(ov_time_total(&vf, -1) + 0.5));
+ const auto total = ov_time_total(&vf, -1);
+ if (total >= 0)
+ tag_handler_invoke_duration(handler, handler_ctx,
+ SongTime::FromS(total));
vorbis_comments_scan(ov_comment(&vf, -1)->user_comments,
handler, handler_ctx);
diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx
index 1efd49850..67859bbd2 100644
--- a/src/decoder/plugins/WavpackDecoderPlugin.cxx
+++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx
@@ -283,9 +283,10 @@ wavpack_scan_file(Path path_fs,
return false;
}
- tag_handler_invoke_duration(handler, handler_ctx,
- WavpackGetNumSamples(wpc) /
- WavpackGetSampleRate(wpc));
+ const auto duration =
+ SongTime::FromScale<uint64_t>(WavpackGetNumSamples(wpc),
+ WavpackGetSampleRate(wpc));
+ tag_handler_invoke_duration(handler, handler_ctx, duration);
/* the WavPack format implies APEv2 tags, which means we can
reuse the mapping from tag_ape.c */
diff --git a/src/decoder/plugins/WildmidiDecoderPlugin.cxx b/src/decoder/plugins/WildmidiDecoderPlugin.cxx
index 221f7433b..fc58f0977 100644
--- a/src/decoder/plugins/WildmidiDecoderPlugin.cxx
+++ b/src/decoder/plugins/WildmidiDecoderPlugin.cxx
@@ -135,7 +135,9 @@ wildmidi_scan_file(Path path_fs,
return false;
}
- int duration = info->approx_total_samples / WILDMIDI_SAMPLE_RATE;
+ const auto duration =
+ SongTime::FromScale<uint64_t>(info->approx_total_samples,
+ WILDMIDI_SAMPLE_RATE);
tag_handler_invoke_duration(handler, handler_ctx, duration);
WildMidi_Close(wm);
diff --git a/src/tag/TagHandler.cxx b/src/tag/TagHandler.cxx
index 20a51f064..2cbb83242 100644
--- a/src/tag/TagHandler.cxx
+++ b/src/tag/TagHandler.cxx
@@ -23,11 +23,11 @@
#include "util/ASCII.hxx"
static void
-add_tag_duration(unsigned seconds, void *ctx)
+add_tag_duration(SongTime duration, void *ctx)
{
TagBuilder &tag = *(TagBuilder *)ctx;
- tag.SetDuration(SignedSongTime::FromS(seconds));
+ tag.SetDuration(duration);
}
static void
diff --git a/src/tag/TagHandler.hxx b/src/tag/TagHandler.hxx
index 6f737bf56..c12b605bc 100644
--- a/src/tag/TagHandler.hxx
+++ b/src/tag/TagHandler.hxx
@@ -22,6 +22,7 @@
#include "check.h"
#include "TagType.h"
+#include "Chrono.hxx"
#include <assert.h>
@@ -30,11 +31,11 @@
*/
struct tag_handler {
/**
- * Declare the duration of a song, in seconds. Do not call
+ * Declare the duration of a song. Do not call
* this when the duration could not be determined, because
* there is no magic value for "unknown duration".
*/
- void (*duration)(unsigned seconds, void *ctx);
+ void (*duration)(SongTime duration, void *ctx);
/**
* A tag has been read.
@@ -53,12 +54,12 @@ struct tag_handler {
static inline void
tag_handler_invoke_duration(const struct tag_handler *handler, void *ctx,
- unsigned seconds)
+ SongTime duration)
{
assert(handler != nullptr);
if (handler->duration != nullptr)
- handler->duration(seconds, ctx);
+ handler->duration(duration, ctx);
}
static inline void
diff --git a/test/read_tags.cxx b/test/read_tags.cxx
index f11b04f7a..67962062c 100644
--- a/test/read_tags.cxx
+++ b/test/read_tags.cxx
@@ -48,9 +48,9 @@
static bool empty = true;
static void
-print_duration(unsigned seconds, gcc_unused void *ctx)
+print_duration(SongTime duration, gcc_unused void *ctx)
{
- printf("duration=%d\n", seconds);
+ printf("duration=%f\n", duration.ToDoubleS());
}
static void