aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-01-03 14:51:47 +0100
committerMax Kellermann <max@duempel.org>2009-01-03 14:51:47 +0100
commit962f2407d2a3579b7125f937d93d04ccbeb9a453 (patch)
treee4e2fd55c02e53f94b3d63be8b8d2f714428f0b9
parent8ebb3196a854d7e870bbbe904b534641df7d5f89 (diff)
downloadmpd-962f2407d2a3579b7125f937d93d04ccbeb9a453.tar.gz
mpd-962f2407d2a3579b7125f937d93d04ccbeb9a453.tar.xz
mpd-962f2407d2a3579b7125f937d93d04ccbeb9a453.zip
pcm_utils: use the custom PRNG for volume dithering
Don't use libc's rand() function, because it is slow. Our own trivial linear congruential generator is good enough for dithering.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/pcm_dither.c6
-rw-r--r--src/pcm_prng.h31
-rw-r--r--src/pcm_utils.c8
4 files changed, 40 insertions, 6 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 1e1e82598..399534da8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -54,6 +54,7 @@ mpd_headers = \
pcm_channels.h \
pcm_resample.h \
pcm_dither.h \
+ pcm_prng.h \
permission.h \
player_thread.h \
player_control.h \
diff --git a/src/pcm_dither.c b/src/pcm_dither.c
index 1296d0926..984949685 100644
--- a/src/pcm_dither.c
+++ b/src/pcm_dither.c
@@ -17,11 +17,7 @@
*/
#include "pcm_dither.h"
-
-static unsigned long prng(unsigned long state)
-{
- return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
-}
+#include "pcm_prng.h"
static int16_t
pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither_24 *dither)
diff --git a/src/pcm_prng.h b/src/pcm_prng.h
new file mode 100644
index 000000000..e961baacd
--- /dev/null
+++ b/src/pcm_prng.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2003-2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PCM_PRNG_H
+#define PCM_PRNG_H
+
+/**
+ * A very simple linear congruential PRNG. It's good enough for PCM
+ * dithering.
+ */
+static unsigned long prng(unsigned long state)
+{
+ return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
+}
+
+#endif
diff --git a/src/pcm_utils.c b/src/pcm_utils.c
index 46c5f2884..a7e7a3990 100644
--- a/src/pcm_utils.c
+++ b/src/pcm_utils.c
@@ -18,6 +18,7 @@
#include "pcm_utils.h"
#include "pcm_channels.h"
+#include "pcm_prng.h"
#include "utils.h"
#include "conf.h"
#include "audio_format.h"
@@ -33,7 +34,12 @@
static inline int
pcm_dither(void)
{
- return (rand() & 511) - (rand() & 511);
+ static unsigned long state;
+ uint32_t r;
+
+ r = state = prng(state);
+
+ return (r & 511) - ((r >> 9) & 511);
}
/**