Commit 31589551 authored by Max Kellermann's avatar Max Kellermann

TagHandler: pass SongTime to duration()

parent d9d97bd1
......@@ -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(),
......
......@@ -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;
}
......
......@@ -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 */
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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)
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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();
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -347,8 +347,10 @@ vorbis_scan_stream(InputStream &is,
if (!vorbis_is_open(&vis, &vf))
return false;
const auto total = ov_time_total(&vf, -1);
if (total >= 0)
tag_handler_invoke_duration(handler, handler_ctx,
(int)(ov_time_total(&vf, -1) + 0.5));
SongTime::FromS(total));
vorbis_comments_scan(ov_comment(&vf, -1)->user_comments,
handler, handler_ctx);
......
......@@ -283,9 +283,10 @@ wavpack_scan_file(Path path_fs,
return false;
}
tag_handler_invoke_duration(handler, handler_ctx,
WavpackGetNumSamples(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 */
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment