From 3158955198fbdc71319cd3418523d851e6d47106 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 29 Aug 2014 22:43:36 +0200 Subject: TagHandler: pass SongTime to duration() --- src/decoder/plugins/AdPlugDecoderPlugin.cxx | 2 +- src/decoder/plugins/AudiofileDecoderPlugin.cxx | 14 +++++++------- src/decoder/plugins/DsdiffDecoderPlugin.cxx | 5 +++-- src/decoder/plugins/DsfDecoderPlugin.cxx | 6 +++--- src/decoder/plugins/FaadDecoderPlugin.cxx | 8 +++----- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 9 ++++++--- src/decoder/plugins/FlacMetadata.cxx | 10 ++++++++++ src/decoder/plugins/FlacMetadata.hxx | 9 --------- src/decoder/plugins/GmeDecoderPlugin.cxx | 2 +- src/decoder/plugins/MadDecoderPlugin.cxx | 8 +++----- src/decoder/plugins/ModplugDecoderPlugin.cxx | 2 +- src/decoder/plugins/Mp4v2DecoderPlugin.cxx | 6 ++++-- src/decoder/plugins/MpcdecDecoderPlugin.cxx | 13 ++++++------- src/decoder/plugins/Mpg123DecoderPlugin.cxx | 7 +++++-- src/decoder/plugins/OpusDecoderPlugin.cxx | 9 ++++++--- src/decoder/plugins/SidplayDecoderPlugin.cxx | 2 +- src/decoder/plugins/SndfileDecoderPlugin.cxx | 5 +++-- src/decoder/plugins/VorbisDecoderPlugin.cxx | 6 ++++-- src/decoder/plugins/WavpackDecoderPlugin.cxx | 7 ++++--- src/decoder/plugins/WildmidiDecoderPlugin.cxx | 4 +++- src/tag/TagHandler.cxx | 4 ++-- src/tag/TagHandler.hxx | 9 +++++---- 22 files changed, 81 insertions(+), 66 deletions(-) (limited to 'src') 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(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 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(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(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(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(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(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(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(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(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(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 @@ -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 -- cgit v1.2.3