summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2018-09-22 19:24:34 +0200
committerMax Kellermann <max@musicpd.org>2018-09-22 19:37:02 +0200
commit224400074c61f667fb6d0d89d7170a4d04ba39b4 (patch)
treeb02aae9496bf02c1596d7eb0275ea6ee3134173a
parent863722545f1d892ce4d30b91f6bf25bb08b48a19 (diff)
player/CrossFade: use std::chrono::duration
-rw-r--r--src/command/PlayerCommands.cxx14
-rw-r--r--src/player/Control.cxx10
-rw-r--r--src/player/Control.hxx8
-rw-r--r--src/player/CrossFade.cxx43
-rw-r--r--src/player/CrossFade.hxx5
-rw-r--r--src/player/Thread.cxx2
-rw-r--r--src/queue/PlaylistState.cxx10
-rw-r--r--test/test_mixramp.cxx18
8 files changed, 56 insertions, 54 deletions
diff --git a/src/command/PlayerCommands.cxx b/src/command/PlayerCommands.cxx
index 27147f373..136baeb10 100644
--- a/src/command/PlayerCommands.cxx
+++ b/src/command/PlayerCommands.cxx
@@ -152,13 +152,13 @@ handle_status(Client &client, gcc_unused Request args, Response &r)
pc.GetMixRampDb(),
state);
- if (pc.GetCrossFade() > 0)
+ if (pc.GetCrossFade() > FloatDuration::zero())
r.Format(COMMAND_STATUS_CROSSFADE ": %lu\n",
- std::lround(pc.GetCrossFade()));
+ std::lround(pc.GetCrossFade().count()));
- if (pc.GetMixRampDelay() > 0)
+ if (pc.GetMixRampDelay() > FloatDuration::zero())
r.Format(COMMAND_STATUS_MIXRAMPDELAY ": %f\n",
- pc.GetMixRampDelay());
+ pc.GetMixRampDelay().count());
song = playlist.GetCurrentPosition();
if (song >= 0) {
@@ -316,8 +316,8 @@ handle_seekcur(Client &client, Request args, gcc_unused Response &r)
CommandResult
handle_crossfade(Client &client, Request args, gcc_unused Response &r)
{
- unsigned xfade_time = args.ParseUnsigned(0);
- client.GetPlayerControl().SetCrossFade(xfade_time);
+ FloatDuration duration{args.ParseUnsigned(0)};
+ client.GetPlayerControl().SetCrossFade(duration);
return CommandResult::OK;
}
@@ -332,7 +332,7 @@ handle_mixrampdb(Client &client, Request args, gcc_unused Response &r)
CommandResult
handle_mixrampdelay(Client &client, Request args, gcc_unused Response &r)
{
- float delay_secs = args.ParseFloat(0);
+ FloatDuration delay_secs{args.ParseFloat(0)};
client.GetPlayerControl().SetMixRampDelay(delay_secs);
return CommandResult::OK;
}
diff --git a/src/player/Control.cxx b/src/player/Control.cxx
index 296b9c431..0b8a695e7 100644
--- a/src/player/Control.cxx
+++ b/src/player/Control.cxx
@@ -283,11 +283,9 @@ PlayerControl::LockSeek(std::unique_ptr<DetachedSong> song, SongTime t)
}
void
-PlayerControl::SetCrossFade(float _cross_fade_seconds) noexcept
+PlayerControl::SetCrossFade(FloatDuration duration) noexcept
{
- if (_cross_fade_seconds < 0)
- _cross_fade_seconds = 0;
- cross_fade.duration = _cross_fade_seconds;
+ cross_fade.duration = std::max(duration, FloatDuration::zero());
idle_add(IDLE_OPTIONS);
}
@@ -301,9 +299,9 @@ PlayerControl::SetMixRampDb(float _mixramp_db) noexcept
}
void
-PlayerControl::SetMixRampDelay(float _mixramp_delay_seconds) noexcept
+PlayerControl::SetMixRampDelay(FloatDuration _mixramp_delay) noexcept
{
- cross_fade.mixramp_delay = _mixramp_delay_seconds;
+ cross_fade.mixramp_delay = _mixramp_delay;
idle_add(IDLE_OPTIONS);
}
diff --git a/src/player/Control.hxx b/src/player/Control.hxx
index f2a85ce2a..3bcb05d58 100644
--- a/src/player/Control.hxx
+++ b/src/player/Control.hxx
@@ -557,9 +557,9 @@ private:
}
public:
- void SetCrossFade(float cross_fade_seconds) noexcept;
+ void SetCrossFade(FloatDuration duration) noexcept;
- float GetCrossFade() const noexcept {
+ auto GetCrossFade() const noexcept {
return cross_fade.duration;
}
@@ -569,9 +569,9 @@ public:
return cross_fade.mixramp_db;
}
- void SetMixRampDelay(float mixramp_delay_seconds) noexcept;
+ void SetMixRampDelay(FloatDuration mixramp_delay) noexcept;
- float GetMixRampDelay() const noexcept {
+ auto GetMixRampDelay() const noexcept {
return cross_fade.mixramp_delay;
}
diff --git a/src/player/CrossFade.cxx b/src/player/CrossFade.cxx
index 82c11223c..b7c5787c4 100644
--- a/src/player/CrossFade.cxx
+++ b/src/player/CrossFade.cxx
@@ -33,10 +33,11 @@
static constexpr Domain cross_fade_domain("cross_fade");
gcc_pure
-static float
+static FloatDuration
mixramp_interpolate(const char *ramp_list, float required_db) noexcept
{
- float last_db = 0, last_secs = 0;
+ float last_db = 0;
+ FloatDuration last_duration = FloatDuration::zero();
bool have_last = false;
/* ramp_list is a string of pairs of dBs and seconds that describe the
@@ -54,7 +55,7 @@ mixramp_interpolate(const char *ramp_list, float required_db) noexcept
ramp_list = endptr + 1;
/* Parse the time. */
- float secs = ParseFloat(ramp_list, &endptr);
+ FloatDuration duration{ParseFloat(ramp_list, &endptr)};
if (endptr == ramp_list || (*endptr != ';' && *endptr != 0))
break;
@@ -64,27 +65,27 @@ mixramp_interpolate(const char *ramp_list, float required_db) noexcept
/* Check for exact match. */
if (db == required_db) {
- return secs;
+ return duration;
}
/* Save if too quiet. */
if (db < required_db) {
last_db = db;
- last_secs = secs;
+ last_duration = duration;
have_last = true;
continue;
}
/* If required db < any stored value, use the least. */
if (!have_last)
- return secs;
+ return duration;
/* Finally, interpolate linearly. */
- secs = last_secs + (required_db - last_db) * (secs - last_secs) / (db - last_db);
- return secs;
+ duration = last_duration + (required_db - last_db) * (duration - last_duration) / (db - last_db);
+ return duration;
}
- return -1;
+ return FloatDuration(-1);
}
unsigned
@@ -99,36 +100,38 @@ CrossFadeSettings::Calculate(SignedSongTime total_time,
float chunks_f;
if (total_time.IsNegative() ||
- duration < 0 || duration >= total_time.ToDoubleS() ||
+ duration <= FloatDuration::zero() ||
+ duration >= std::chrono::duration_cast<FloatDuration>(total_time) ||
/* we can't crossfade when the audio formats are different */
af != old_format)
return 0;
- assert(duration >= 0);
+ assert(duration > FloatDuration::zero());
assert(af.IsValid());
chunks_f = (float)af.GetTimeToSize() / (float)sizeof(MusicChunk::data);
- if (mixramp_delay <= 0 || !mixramp_start || !mixramp_prev_end) {
- chunks = std::lround(chunks_f * duration);
+ if (mixramp_delay <= FloatDuration::zero() ||
+ !mixramp_start || !mixramp_prev_end) {
+ chunks = std::lround(chunks_f * duration.count());
} else {
/* Calculate mixramp overlap. */
- const float mixramp_overlap_current =
+ const auto mixramp_overlap_current =
mixramp_interpolate(mixramp_start,
mixramp_db - replay_gain_db);
- const float mixramp_overlap_prev =
+ const auto mixramp_overlap_prev =
mixramp_interpolate(mixramp_prev_end,
mixramp_db - replay_gain_prev_db);
- const float mixramp_overlap =
+ const auto mixramp_overlap =
mixramp_overlap_current + mixramp_overlap_prev;
- if (mixramp_overlap_current >= 0 &&
- mixramp_overlap_prev >= 0 &&
+ if (mixramp_overlap_current >= FloatDuration::zero() &&
+ mixramp_overlap_prev >= FloatDuration::zero() &&
mixramp_delay <= mixramp_overlap) {
- chunks = (chunks_f * (mixramp_overlap - mixramp_delay));
+ chunks = (chunks_f * (mixramp_overlap - mixramp_delay).count());
FormatDebug(cross_fade_domain,
"will overlap %d chunks, %fs", chunks,
- mixramp_overlap - mixramp_delay);
+ (mixramp_overlap - mixramp_delay).count());
}
}
diff --git a/src/player/CrossFade.hxx b/src/player/CrossFade.hxx
index 2bdd3f0a0..67effd1f0 100644
--- a/src/player/CrossFade.hxx
+++ b/src/player/CrossFade.hxx
@@ -20,6 +20,7 @@
#ifndef MPD_CROSSFADE_HXX
#define MPD_CROSSFADE_HXX
+#include "Chrono.hxx"
#include "util/Compiler.h"
struct AudioFormat;
@@ -29,7 +30,7 @@ struct CrossFadeSettings {
/**
* The configured cross fade duration [s].
*/
- float duration;
+ FloatDuration duration;
float mixramp_db;
@@ -37,7 +38,7 @@ struct CrossFadeSettings {
* The configured MixRapm delay [s]. A non-positive value
* disables MixRamp.
*/
- float mixramp_delay;
+ FloatDuration mixramp_delay;
CrossFadeSettings()
:duration(0),
diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx
index 9c8af5e90..ab0a35141 100644
--- a/src/player/Thread.cxx
+++ b/src/player/Thread.cxx
@@ -809,7 +809,7 @@ Player::PlayNextChunk() noexcept
cross_fade_tag = Tag::Merge(std::move(cross_fade_tag),
std::move(other_chunk->tag));
- if (pc.cross_fade.mixramp_delay <= 0) {
+ if (pc.cross_fade.mixramp_delay <= FloatDuration::zero()) {
chunk->mix_ratio = ((float)cross_fade_position)
/ cross_fade_chunks;
} else {
diff --git a/src/queue/PlaylistState.cxx b/src/queue/PlaylistState.cxx
index 33e701aca..f4b7bdef6 100644
--- a/src/queue/PlaylistState.cxx
+++ b/src/queue/PlaylistState.cxx
@@ -92,10 +92,10 @@ playlist_state_save(BufferedOutputStream &os, const struct playlist &playlist,
(int)playlist.queue.single);
os.Format(PLAYLIST_STATE_FILE_CONSUME "%i\n", playlist.queue.consume);
os.Format(PLAYLIST_STATE_FILE_CROSSFADE "%i\n",
- (int)pc.GetCrossFade());
+ (int)pc.GetCrossFade().count());
os.Format(PLAYLIST_STATE_FILE_MIXRAMPDB "%f\n", pc.GetMixRampDb());
os.Format(PLAYLIST_STATE_FILE_MIXRAMPDELAY "%f\n",
- pc.GetMixRampDelay());
+ pc.GetMixRampDelay().count());
os.Write(PLAYLIST_STATE_FILE_PLAYLIST_BEGIN "\n");
queue_save(os, playlist.queue);
os.Write(PLAYLIST_STATE_FILE_PLAYLIST_END "\n");
@@ -159,14 +159,14 @@ playlist_state_restore(const StateFileConfig &config,
} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_CONSUME))) {
playlist.SetConsume(StringIsEqual(p, "1"));
} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_CROSSFADE))) {
- pc.SetCrossFade(atoi(p));
+ pc.SetCrossFade(FloatDuration(atoi(p)));
} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_MIXRAMPDB))) {
pc.SetMixRampDb(ParseFloat(p));
} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_MIXRAMPDELAY))) {
/* this check discards "nan" which was used
prior to MPD 0.18 */
if (IsDigitASCII(*p))
- pc.SetMixRampDelay(ParseFloat(p));
+ pc.SetMixRampDelay(FloatDuration(ParseFloat(p)));
} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_RANDOM))) {
random_mode = StringIsEqual(p, "1");
} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_CURRENT))) {
@@ -232,7 +232,7 @@ playlist_state_get_hash(const playlist &playlist,
(playlist.current >= 0
? (playlist.queue.OrderToPosition(playlist.current) << 16)
: 0) ^
- ((int)pc.GetCrossFade() << 20) ^
+ ((int)pc.GetCrossFade().count() << 20) ^
(unsigned(player_status.state) << 24) ^
/* note that this takes 2 bits */
((int)playlist.queue.single << 25) ^
diff --git a/test/test_mixramp.cxx b/test/test_mixramp.cxx
index ea245f72f..898452c89 100644
--- a/test/test_mixramp.cxx
+++ b/test/test_mixramp.cxx
@@ -23,53 +23,53 @@ public:
char *foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(double(0),
- mixramp_interpolate(foo, 0),
+ mixramp_interpolate(foo, 0).count(),
0.05);
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(0),
- mixramp_interpolate(foo, 1),
+ mixramp_interpolate(foo, 1).count(),
0.005);
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(0.1),
- mixramp_interpolate(foo, 3),
+ mixramp_interpolate(foo, 3).count(),
0.005);
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(2.5),
- mixramp_interpolate(foo, 6),
+ mixramp_interpolate(foo, 6).count(),
0.01);
free(foo);
foo = strdup(input);
- CPPUNIT_ASSERT(mixramp_interpolate(foo, 6.1) < 0);
+ CPPUNIT_ASSERT(mixramp_interpolate(foo, 6.1) < FloatDuration::zero());
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(0.05),
- mixramp_interpolate(foo, 2),
+ mixramp_interpolate(foo, 2).count(),
0.05);
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(1.3),
- mixramp_interpolate(foo, 4.5),
+ mixramp_interpolate(foo, 4.5).count(),
0.05);
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(0.9),
- mixramp_interpolate(foo, 4),
+ mixramp_interpolate(foo, 4).count(),
0.05);
free(foo);
foo = strdup(input);
CPPUNIT_ASSERT_DOUBLES_EQUAL(float(1.7),
- mixramp_interpolate(foo, 5),
+ mixramp_interpolate(foo, 5).count(),
0.05);
free(foo);
}