TagHandler: pass SongTime to duration()
This commit is contained in:
parent
d9d97bd17b
commit
3158955198
@ -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;
|
||||
|
||||
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);
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user