From 49a3845135142ada6d581d5a6f4a5192aaed49be Mon Sep 17 00:00:00 2001 From: Denis Krjuchkov Date: Sun, 12 May 2013 19:03:42 +0600 Subject: timer: convert to class --- Makefile.am | 6 +-- src/Timer.cxx | 80 ++++++++++++++++++++++++++++++++++++ src/Timer.hxx | 49 ++++++++++++++++++++++ src/clock.h | 8 ++++ src/output/FifoOutputPlugin.cxx | 20 ++++----- src/output/HttpdInternal.hxx | 6 +-- src/output/HttpdOutputPlugin.cxx | 16 ++++---- src/output/NullOutputPlugin.cxx | 22 +++++----- src/timer.c | 89 ---------------------------------------- src/timer.h | 59 -------------------------- 10 files changed, 172 insertions(+), 183 deletions(-) create mode 100644 src/Timer.cxx create mode 100644 src/Timer.hxx delete mode 100644 src/timer.c delete mode 100644 src/timer.h diff --git a/Makefile.am b/Makefile.am index 695b43a5e..a8d077bdd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -94,7 +94,7 @@ mpd_headers = \ src/tag_ape.h \ src/tag_id3.h \ src/tag_rva2.h \ - src/timer.h \ + src/Timer.hxx \ src/mpd_error.h src_mpd_SOURCES = \ @@ -243,7 +243,7 @@ src_mpd_SOURCES = \ src/SongFilter.cxx src/SongFilter.hxx \ src/SongPointer.hxx \ src/PlaylistFile.cxx src/PlaylistFile.hxx \ - src/timer.c + src/Timer.cxx # # Windows resource file @@ -1299,7 +1299,7 @@ test_run_output_SOURCES = test/run_output.cxx \ src/audio_check.c \ src/audio_format.c \ src/AudioParser.cxx \ - src/timer.c src/clock.c \ + src/Timer.cxx src/clock.c \ src/Tag.cxx src/TagNames.c src/TagPool.cxx \ src/Page.cxx \ src/SocketUtil.cxx \ diff --git a/src/Timer.cxx b/src/Timer.cxx new file mode 100644 index 000000000..7ddbda3da --- /dev/null +++ b/src/Timer.cxx @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2003-2011 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "Timer.hxx" +#include "audio_format.h" +#include "clock.h" + +#include + +#include +#include +#include + +Timer::Timer(const struct audio_format &af) + : time(0), + started(false), + rate(af.sample_rate * audio_format_frame_size(&af)) +{ +} + +void Timer::Start() +{ + time = monotonic_clock_us(); + started = true; +} + +void Timer::Reset() +{ + time = 0; + started = false; +} + +void Timer::Add(int size) +{ + assert(started); + + // (size samples) / (rate samples per second) = duration seconds + // duration seconds * 1000000 = duration us + time += ((uint64_t)size * 1000000) / rate; +} + +unsigned Timer::GetDelay() const +{ + int64_t delay = (int64_t)(time - monotonic_clock_us()) / 1000; + if (delay < 0) + return 0; + + if (delay > G_MAXINT) + delay = G_MAXINT; + + return delay; +} + +void Timer::Synchronize() const +{ + int64_t sleep_duration; + + assert(started); + + sleep_duration = time - monotonic_clock_us(); + if (sleep_duration > 0) + g_usleep(sleep_duration); +} diff --git a/src/Timer.hxx b/src/Timer.hxx new file mode 100644 index 000000000..96446a988 --- /dev/null +++ b/src/Timer.hxx @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2003-2011 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_TIMER_HXX +#define MPD_TIMER_HXX + +#include + +struct audio_format; + +class Timer { + uint64_t time; + bool started; + const int rate; +public: + explicit Timer(const struct audio_format& af); + + bool IsStarted() const { return started; } + + void Start(); + void Reset(); + + void Add(int size); + + /** + * Returns the number of milliseconds to sleep to get back to sync. + */ + unsigned GetDelay() const; + + void Synchronize() const; +}; + +#endif diff --git a/src/clock.h b/src/clock.h index f1338938f..c98b9a652 100644 --- a/src/clock.h +++ b/src/clock.h @@ -24,6 +24,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Returns the value of a monotonic clock in milliseconds. */ @@ -38,4 +42,8 @@ gcc_pure uint64_t monotonic_clock_us(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/output/FifoOutputPlugin.cxx b/src/output/FifoOutputPlugin.cxx index ebebc254f..15b107c45 100644 --- a/src/output/FifoOutputPlugin.cxx +++ b/src/output/FifoOutputPlugin.cxx @@ -20,7 +20,7 @@ #include "config.h" #include "FifoOutputPlugin.hxx" #include "output_api.h" -#include "timer.h" +#include "Timer.hxx" #include "fd_util.h" #include "open.h" @@ -44,7 +44,7 @@ struct FifoOutput { int input; int output; bool created; - struct timer *timer; + Timer *timer; FifoOutput() :path(nullptr), input(-1), output(-1), created(false) {} @@ -232,7 +232,7 @@ fifo_output_open(struct audio_output *ao, struct audio_format *audio_format, { FifoOutput *fd = (FifoOutput *)ao; - fd->timer = timer_new(audio_format); + fd->timer = new Timer(*audio_format); return true; } @@ -242,7 +242,7 @@ fifo_output_close(struct audio_output *ao) { FifoOutput *fd = (FifoOutput *)ao; - timer_free(fd->timer); + delete fd->timer; } static void @@ -252,7 +252,7 @@ fifo_output_cancel(struct audio_output *ao) char buf[FIFO_BUFFER_SIZE]; int bytes = 1; - timer_reset(fd->timer); + fd->timer->Reset(); while (bytes > 0 && errno != EINTR) bytes = read(fd->input, buf, FIFO_BUFFER_SIZE); @@ -268,8 +268,8 @@ fifo_output_delay(struct audio_output *ao) { FifoOutput *fd = (FifoOutput *)ao; - return fd->timer->started - ? timer_delay(fd->timer) + return fd->timer->IsStarted() + ? fd->timer->GetDelay() : 0; } @@ -280,9 +280,9 @@ fifo_output_play(struct audio_output *ao, const void *chunk, size_t size, FifoOutput *fd = (FifoOutput *)ao; ssize_t bytes; - if (!fd->timer->started) - timer_start(fd->timer); - timer_add(fd->timer, size); + if (!fd->timer->IsStarted()) + fd->timer->Start(); + fd->timer->Add(size); while (true) { bytes = write(fd->output, chunk, size); diff --git a/src/output/HttpdInternal.hxx b/src/output/HttpdInternal.hxx index e79b9a224..b79a22905 100644 --- a/src/output/HttpdInternal.hxx +++ b/src/output/HttpdInternal.hxx @@ -26,7 +26,7 @@ #define MPD_OUTPUT_HTTPD_INTERNAL_H #include "OutputInternal.hxx" -#include "timer.h" +#include "Timer.hxx" #include "thread/Mutex.hxx" #include "event/ServerSocket.hxx" @@ -72,10 +72,10 @@ struct HttpdOutput final : private ServerSocket { mutable Mutex mutex; /** - * A #timer object to synchronize this output with the + * A #Timer object to synchronize this output with the * wallclock. */ - struct timer *timer; + Timer *timer; /** * The header page, which is sent to every client on connect. diff --git a/src/output/HttpdOutputPlugin.cxx b/src/output/HttpdOutputPlugin.cxx index bb644c318..2c4884827 100644 --- a/src/output/HttpdOutputPlugin.cxx +++ b/src/output/HttpdOutputPlugin.cxx @@ -320,7 +320,7 @@ HttpdOutput::Open(struct audio_format *audio_format, GError **error_r) /* initialize other attributes */ clients_cnt = 0; - timer = timer_new(audio_format); + timer = new Timer(*audio_format); open = true; @@ -346,7 +346,7 @@ HttpdOutput::Close() open = false; - timer_free(timer); + delete timer; clients.clear(); @@ -398,7 +398,7 @@ httpd_output_delay(struct audio_output *ao) then httpd_output_pause() will not do anything, it will not fill the buffer and it will not update the timer; therefore, we reset the timer here */ - timer_reset(httpd->timer); + httpd->timer->Reset(); /* some arbitrary delay that is long enough to avoid consuming too much CPU, and short enough to notice @@ -406,8 +406,8 @@ httpd_output_delay(struct audio_output *ao) return 1000; } - return httpd->timer->started - ? timer_delay(httpd->timer) + return httpd->timer->IsStarted() + ? httpd->timer->GetDelay() : 0; } @@ -463,9 +463,9 @@ httpd_output_play(struct audio_output *ao, const void *chunk, size_t size, return 0; } - if (!httpd->timer->started) - timer_start(httpd->timer); - timer_add(httpd->timer, size); + if (!httpd->timer->IsStarted()) + httpd->timer->Start(); + httpd->timer->Add(size); return size; } diff --git a/src/output/NullOutputPlugin.cxx b/src/output/NullOutputPlugin.cxx index bbcf26c00..b167032b6 100644 --- a/src/output/NullOutputPlugin.cxx +++ b/src/output/NullOutputPlugin.cxx @@ -20,7 +20,7 @@ #include "config.h" #include "NullOutputPlugin.hxx" #include "output_api.h" -#include "timer.h" +#include "Timer.hxx" #include @@ -29,7 +29,7 @@ struct NullOutput { bool sync; - struct timer *timer; + Timer *timer; bool Initialize(const config_param *param, GError **error_r) { return ao_base_init(&base, &null_output_plugin, param, @@ -72,7 +72,7 @@ null_open(struct audio_output *ao, struct audio_format *audio_format, NullOutput *nd = (NullOutput *)ao; if (nd->sync) - nd->timer = timer_new(audio_format); + nd->timer = new Timer(*audio_format); return true; } @@ -83,7 +83,7 @@ null_close(struct audio_output *ao) NullOutput *nd = (NullOutput *)ao; if (nd->sync) - timer_free(nd->timer); + delete nd->timer; } static unsigned @@ -91,8 +91,8 @@ null_delay(struct audio_output *ao) { NullOutput *nd = (NullOutput *)ao; - return nd->sync && nd->timer->started - ? timer_delay(nd->timer) + return nd->sync && nd->timer->IsStarted() + ? nd->timer->GetDelay() : 0; } @@ -101,14 +101,14 @@ null_play(struct audio_output *ao, gcc_unused const void *chunk, size_t size, gcc_unused GError **error) { NullOutput *nd = (NullOutput *)ao; - struct timer *timer = nd->timer; + Timer *timer = nd->timer; if (!nd->sync) return size; - if (!timer->started) - timer_start(timer); - timer_add(timer, size); + if (!timer->IsStarted()) + timer->Start(); + timer->Add(size); return size; } @@ -121,7 +121,7 @@ null_cancel(struct audio_output *ao) if (!nd->sync) return; - timer_reset(nd->timer); + nd->timer->Reset(); } const struct audio_output_plugin null_output_plugin = { diff --git a/src/timer.c b/src/timer.c deleted file mode 100644 index 9a3228465..000000000 --- a/src/timer.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "timer.h" -#include "audio_format.h" -#include "clock.h" - -#include - -#include -#include -#include - -struct timer *timer_new(const struct audio_format *af) -{ - struct timer *timer = g_new(struct timer, 1); - timer->time = 0; // us - timer->started = 0; // false - timer->rate = af->sample_rate * audio_format_frame_size(af); // samples per second - - return timer; -} - -void timer_free(struct timer *timer) -{ - g_free(timer); -} - -void timer_start(struct timer *timer) -{ - timer->time = monotonic_clock_us(); - timer->started = 1; -} - -void timer_reset(struct timer *timer) -{ - timer->time = 0; - timer->started = 0; -} - -void timer_add(struct timer *timer, int size) -{ - assert(timer->started); - - // (size samples) / (rate samples per second) = duration seconds - // duration seconds * 1000000 = duration us - timer->time += ((uint64_t)size * 1000000) / timer->rate; -} - -unsigned -timer_delay(const struct timer *timer) -{ - int64_t delay = (int64_t)(timer->time - monotonic_clock_us()) / 1000; - if (delay < 0) - return 0; - - if (delay > G_MAXINT) - delay = G_MAXINT; - - return delay; -} - -void timer_sync(struct timer *timer) -{ - int64_t sleep_duration; - - assert(timer->started); - - sleep_duration = timer->time - monotonic_clock_us(); - if (sleep_duration > 0) - g_usleep(sleep_duration); -} diff --git a/src/timer.h b/src/timer.h deleted file mode 100644 index 1506c9173..000000000 --- a/src/timer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPD_TIMER_H -#define MPD_TIMER_H - -#include - -struct audio_format; - -struct timer { - uint64_t time; - int started; - int rate; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -struct timer *timer_new(const struct audio_format *af); - -void timer_free(struct timer *timer); - -void timer_start(struct timer *timer); - -void timer_reset(struct timer *timer); - -void timer_add(struct timer *timer, int size); - -/** - * Returns the number of milliseconds to sleep to get back to sync. - */ -unsigned -timer_delay(const struct timer *timer); - -void timer_sync(struct timer *timer); - -#ifdef __cplusplus -} -#endif - -#endif -- cgit v1.2.3