annotate src/madplug/dither.c @ 610:862190d39e00 trunk

[svn] - add madplug. It is not yet hooked up, I'll do that later.
author nenolod
date Mon, 05 Feb 2007 12:28:01 -0800
parents
children 7e14701aef54
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
610
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
1 /* A C-program for MT19937: Integer version */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
2 /* genrand() generates one pseudorandom unsigned integer (32bit) */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
3 /* which is uniformly distributed among 0 to 2^32-1 for each */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
4 /* call. sgenrand(seed) set initial values to the working area */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
5 /* of 624 words. Before genrand(), sgenrand(seed) must be */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
6 /* called once. (seed is any 32-bit integer except for 0). */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
7 /* Coded by Takuji Nishimura, considering the suggestions by */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
8 /* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
9
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
10 /* This library is free software; you can redistribute it and/or */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
11 /* modify it under the terms of the GNU Library General Public */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
12 /* License as published by the Free Software Foundation; either */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
13 /* version 2 of the License, or (at your option) any later */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
14 /* version. */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
15 /* This library is distributed in the hope that it will be useful, */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
16 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
17 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
18 /* See the GNU Library General Public License for more details. */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
19 /* You should have received a copy of the GNU Library General */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
20 /* Public License along with this library; if not, write to the */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
21 /* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
22 /* 02111-1307 USA */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
23
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
24 /* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
25 /* Any feedback is very welcome. For any question, comments, */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
26 /* see http://www.math.keio.ac.jp/matumoto/emt.html or email */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
27 /* matumoto@math.keio.ac.jp */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
28
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
29 #include <stdio.h>
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
30 #include <assert.h>
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
31
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
32
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
33 /* Period parameters */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
34 #define N 624
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
35 #define M 397
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
36 #define MATRIX_A 0x9908b0df /* constant vector a */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
37 #define UPPER_MASK 0x80000000 /* most significant w-r bits */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
38 #define LOWER_MASK 0x7fffffff /* least significant r bits */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
39
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
40 /* Tempering parameters */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
41 #define TEMPERING_MASK_B 0x9d2c5680
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
42 #define TEMPERING_MASK_C 0xefc60000
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
43 #define TEMPERING_SHIFT_U(y) (y >> 11)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
44 #define TEMPERING_SHIFT_S(y) (y << 7)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
45 #define TEMPERING_SHIFT_T(y) (y << 15)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
46 #define TEMPERING_SHIFT_L(y) (y >> 18)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
47
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
48 static unsigned long mt[N]; /* the array for the state vector */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
49 static int mti = N + 1; /* mti==N+1 means mt[N] is not initialized */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
50
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
51 /* initializing the array with a NONZERO seed */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
52 void sgenrand(seed)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
53 unsigned long seed;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
54 {
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
55 /* setting initial seeds to mt[N] using */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
56 /* the generator Line 25 of Table 1 in */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
57 /* [KNUTH 1981, The Art of Computer Programming */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
58 /* Vol. 2 (2nd Ed.), pp102] */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
59 mt[0] = seed & 0xffffffff;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
60 for (mti = 1; mti < N; mti++)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
61 mt[mti] = (69069 * mt[mti - 1]) & 0xffffffff;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
62 }
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
63
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
64 unsigned long genrand()
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
65 {
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
66 unsigned long y;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
67 static unsigned long mag01[2] = { 0x0, MATRIX_A };
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
68 /* mag01[x] = x * MATRIX_A for x=0,1 */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
69
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
70 if (mti >= N) { /* generate N words at one time */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
71 int kk;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
72
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
73 if (mti == N + 1) /* if sgenrand() has not been called, */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
74 sgenrand(4357); /* a default initial seed is used */
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
75
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
76 for (kk = 0; kk < N - M; kk++) {
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
77 y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
78 mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1];
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
79 }
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
80 for (; kk < N - 1; kk++) {
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
81 y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
82 mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1];
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
83 }
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
84 y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
85 mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1];
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
86
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
87 mti = 0;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
88 }
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
89
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
90 y = mt[mti++];
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
91 y ^= TEMPERING_SHIFT_U(y);
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
92 y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
93 y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
94 y ^= TEMPERING_SHIFT_L(y);
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
95
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
96 return y;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
97 }
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
98
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
99 long triangular_dither_noise(int nbits)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
100 {
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
101 // parameter nbits : the peak-to-peak amplitude desired (in bits)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
102 // use with nbits set to 2 + nber of bits to be trimmed.
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
103 // (because triangular is made from two uniformly distributed processes,
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
104 // it starts at 2 bits peak-to-peak amplitude)
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
105 // see The Theory of Dithered Quantization by Robert Alexander Wannamaker
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
106 // for complete proof of why that's optimal
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
107
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
108 long v = (genrand() / 2 - genrand() / 2); // in ]-2^31, 2^31[
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
109 //int signe = (v>0) ? 1 : -1;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
110 long P = 1 << (32 - nbits); // the power of 2
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
111 v /= P;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
112 // now v in ]-2^(nbits-1), 2^(nbits-1) [
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
113
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
114 return v;
862190d39e00 [svn] - add madplug. It is not yet hooked up, I'll do that later.
nenolod
parents:
diff changeset
115 }