Commit d3d1d377 authored by Max Kellermann's avatar Max Kellermann

AudioFormat: add TimeToSize(), SizeToTime()

parent 1a2012a9
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "pcm/SampleFormat.hxx" #include "pcm/SampleFormat.hxx"
#include "util/Compiler.h" #include "util/Compiler.h"
#include <chrono>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
...@@ -152,6 +154,28 @@ struct AudioFormat { ...@@ -152,6 +154,28 @@ struct AudioFormat {
* span to a storage size in bytes. * span to a storage size in bytes.
*/ */
double GetTimeToSize() const; double GetTimeToSize() const;
template<typename D>
constexpr auto TimeToFrames(D t) const noexcept {
using Period = typename D::period;
return ((t.count() * sample_rate) / Period::den) * Period::num;
}
template<typename D>
constexpr size_t TimeToSize(D t) const noexcept {
return size_t(size_t(TimeToFrames(t)) * GetFrameSize());
}
template<typename D>
constexpr D FramesToTime(std::uintmax_t size) const noexcept {
using Period = typename D::period;
return D(((size / Period::num) * Period::den) / sample_rate);
}
template<typename D>
constexpr D SizeToTime(std::uintmax_t size) const noexcept {
return FramesToTime<D>(size / GetFrameSize());
}
}; };
/** /**
......
...@@ -532,8 +532,7 @@ DecoderBridge::SubmitData(InputStream *is, ...@@ -532,8 +532,7 @@ DecoderBridge::SubmitData(InputStream *is,
data = (const uint8_t *)data + nbytes; data = (const uint8_t *)data + nbytes;
length -= nbytes; length -= nbytes;
timestamp += FloatDuration((double)nbytes / timestamp += dc.out_audio_format.SizeToTime<FloatDuration>(nbytes);
dc.out_audio_format.GetTimeToSize());
} }
absolute_frame += data_frames; absolute_frame += data_frames;
......
...@@ -183,7 +183,7 @@ HybridDsdDecode(DecoderClient &client, InputStream &input) ...@@ -183,7 +183,7 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
try { try {
auto result = FindHybridDsdData(client, input); auto result = FindHybridDsdData(client, input);
auto duration = SignedSongTime::FromS(result.second / result.first.GetTimeToSize()); auto duration = result.first.SizeToTime<SignedSongTime>(result.second);
client.Ready(result.first, true, duration); client.Ready(result.first, true, duration);
frame_size = result.first.GetFrameSize(); frame_size = result.first.GetFrameSize();
kbit_rate = frame_size * result.first.sample_rate / kbit_rate = frame_size * result.first.sample_rate /
......
...@@ -264,8 +264,7 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs) ...@@ -264,8 +264,7 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs)
client.SeekError(); client.SeekError();
else { else {
client.CommandFinished(); client.CommandFinished();
client.SubmitTimestamp(FloatDuration(c) client.SubmitTimestamp(audio_format.FramesToTime<FloatDuration>(c));
/ audio_format.sample_rate);
} }
cmd = DecoderCommand::NONE; cmd = DecoderCommand::NONE;
......
...@@ -766,7 +766,7 @@ PlayerControl::PlayChunk(DetachedSong &song, MusicChunkPtr chunk, ...@@ -766,7 +766,7 @@ PlayerControl::PlayChunk(DetachedSong &song, MusicChunkPtr chunk,
const double chunk_length(chunk->length); const double chunk_length(chunk->length);
outputs.Play(std::move(chunk)); outputs.Play(std::move(chunk));
total_play_time += FloatDuration(chunk_length / format.GetTimeToSize()); total_play_time += format.SizeToTime<decltype(total_play_time)>(chunk_length);
} }
inline bool inline bool
......
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