Subversion Repositories filter_foundry

Rev

Rev 288 | Rev 290 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 288 Rev 289
Line 171... Line 171...
171
/* dif(a,b) Absolute value of the difference of a and b */
171
/* dif(a,b) Absolute value of the difference of a and b */
172
value_type ff_dif(value_type a,value_type b){
172
value_type ff_dif(value_type a,value_type b){
173
        return abs(a-b);
173
        return abs(a-b);
174
}
174
}
175
 
175
 
176
uint16_t gFactoryRndIndexCounter = 0;
176
uint16_t gFactoryRndIndexCounter1 = 0;
-
 
177
uint16_t gFactoryRndIndexCounter2 = 31;
177
uint32_t gFactoryRndLookup[56];
178
uint32_t gFactoryRndLookup[56];
178
uint32_t gFactoryRndSeed;
179
uint32_t gFactoryRndSeed;
179
uint32_t gFactoryRndSeedSave;
180
uint32_t gFactoryRndSeedSave;
180
 
181
 
181
void factory_fill_rnd_lookup(uint32_t seed);
182
void factory_fill_rnd_lookup(uint32_t seed);
182
 
183
 
183
uint32_t factory_rnd(uint32_t a, uint32_t b) {
184
uint32_t factory_rnd(uint32_t a, uint32_t b) {
184
        uint16_t rndCounterA, rndCounterB;
185
        uint32_t mj; // Note: This must be "uint32_t". With "long" (as described by Knuth), it won't match FilterFactory's algorithm
185
        uint32_t result;
-
 
186
        int32_t range;
186
        int range;
187
 
187
 
188
        if (gFactoryRndSeed != gFactoryRndSeedSave) {
188
        if (gFactoryRndSeed != gFactoryRndSeedSave) {
189
                // (Intentional) behavior of Filter Foundry
189
                // (Intentional) behavior of Filter Foundry
190
                factory_fill_rnd_lookup(gFactoryRndSeed);
190
                factory_fill_rnd_lookup(gFactoryRndSeed);
191
                gFactoryRndIndexCounter = 0;
191
                gFactoryRndIndexCounter1 = 0;
-
 
192
                gFactoryRndIndexCounter2 = 31;
192
        }
193
        }
193
 
194
 
194
        // Algorithm of Filter Factory
195
        // Algorithm of Filter Factory
-
 
196
        // Filter Factory uses Donald E.Knuth's subtractive
-
 
197
        // random number generator algorithm ("ran3"), which has been published
-
 
198
        // in Page 283 of "The Art of Computer Programming, volume 2: Seminumerical Algorithms",
-
 
199
        // Addison-Wesley, Reading, MA, second edition, 1981.
-
 
200
        // https://www.cec.uchile.cl/cinetica/pcordero/MC_libros/NumericalRecipesinC.pdf (PDF Page 307)
195
 
201
 
196
        rndCounterA = gFactoryRndIndexCounter % 55 + 1;
202
        if (++gFactoryRndIndexCounter1 == 56) gFactoryRndIndexCounter1 = 1;
197
        rndCounterB = (gFactoryRndIndexCounter + 31) % 55 + 1;
-
 
198
        gFactoryRndIndexCounter = rndCounterA;
203
        if (++gFactoryRndIndexCounter2 == 56) gFactoryRndIndexCounter2 = 1;
199
 
204
 
-
 
205
        mj = gFactoryRndLookup[gFactoryRndIndexCounter1] -
200
        result = gFactoryRndLookup[rndCounterA] - gFactoryRndLookup[rndCounterB];
206
             gFactoryRndLookup[gFactoryRndIndexCounter2];
201
        gFactoryRndLookup[rndCounterA] = result;
207
        gFactoryRndLookup[gFactoryRndIndexCounter1] = mj;
202
 
208
 
-
 
209
        // This is Filter Factory specific:
203
        // Scale result to interval [a..b]
210
        // Squeeze result into interval [a..b]
-
 
211
        if (a == 0) {
-
 
212
                // This part is optional; it is intended to increase the
-
 
213
                // performance by avoiding modulo/divide if possible.
-
 
214
                switch (b) {
-
 
215
                case 255:
-
 
216
                        return mj & 0xFF;
-
 
217
                case 127:
-
 
218
                        return mj & 0x7F;
-
 
219
                case 63:
-
 
220
                        return mj & 0x3F;
-
 
221
                case 31:
-
 
222
                        return mj & 0x1F;
-
 
223
                case 15:
-
 
224
                        return mj & 0xF;
-
 
225
                case 7:
-
 
226
                        return mj & 0x7;
-
 
227
                case 3:
-
 
228
                        return mj & 0x3;
-
 
229
                case 1:
-
 
230
                        return mj & 0x1;
-
 
231
                }
-
 
232
        }
204
        range = b - a;
233
        range = b - a;
205
        if (range < 0) return 0;
234
        if (range < 0) return 0;
206
        return a + (result % (range + 1));
235
        return a + (mj % (range + 1));
207
}
236
}
208
 
237
 
209
void factory_fill_rnd_lookup(uint32_t seed) {
238
void factory_fill_rnd_lookup(uint32_t seed) {
210
        // Algorithm of Filter Factory
239
        // Algorithm of Filter Factory
-
 
240
        // Filter Factory uses Donald E.Knuth's subtractive
-
 
241
        // random number generator algorithm ("ran3"), which has been published
-
 
242
        // in Page 283 of "The Art of Computer Programming, volume 2: Seminumerical Algorithms",
-
 
243
        // Addison-Wesley, Reading, MA, second edition, 1981.
-
 
244
        // https://www.cec.uchile.cl/cinetica/pcordero/MC_libros/NumericalRecipesinC.pdf (PDF Page 307)
211
 
245
 
212
        uint32_t i, j;
246
        long mj, mk;
213
        uint32_t v1, v2, v3;
247
        int i, ii, k;
214
 
248
 
215
        // 161803398 = 1.61803398 * 10^8 ~= phi * 10^8
249
        // 161803398 = 1.61803398 * 10^8 ~= phi * 10^8
216
        v2 = 161803398 - (seed & 0x7fff);
250
        mj = 161803398 - (seed & 0x7fff);
217
        gFactoryRndLookup[55] = v2;
251
        gFactoryRndLookup[55] = mj;
218
 
252
 
219
        v3 = 1;
253
        mk = 1;
220
        for (i=1; i<55; ++i) {
254
        for (i=1; i<=54; ++i) {
221
                v1 = v3;
255
                ii = (21 * i) % 55;
222
                gFactoryRndLookup[(i * 21) % 55] = v1;
256
                gFactoryRndLookup[ii] = mk;
223
                v3 = v2 - v1;
257
                mk = mj - mk;
224
                v2 = v1;
258
                mj = gFactoryRndLookup[ii];
225
        }
259
        }
226
 
260
 
227
        for (i=0; i<4; ++i) {
261
        for (k=1; k<=4; ++k) {
228
                for (j=1; j<=55;) {
262
                for (i=1; i<=55; ++i) {
229
                        gFactoryRndLookup[j++] = gFactoryRndLookup[j] - gFactoryRndLookup[((j + 30) % 55) + 1];
263
                        gFactoryRndLookup[i] -= gFactoryRndLookup[1+(i + 30) % 55];
230
                }
264
                }
231
        }
265
        }
232
 
266
 
233
        gFactoryRndSeedSave = seed;
267
        gFactoryRndSeedSave = seed;
234
 
268