Reply by Andreas Huennebeck●July 19, 20062006-07-19
bademiya wrote:
>>However, I'm very sure that the data go to a DAC with 8 or more bits,
>>so an integer division should be good enough for the generation of
> noise:
>>
>>const int dac_bits = 8; /* or 12 or 16 or whatever the documentation says) */
>>const int range = 1 << dac_bits;
>>const int max_amplitude = range / 2;
>>const int fact = (double)range / (double)RAND_MAX;
>>for(i = 0; i < 5000; i++) {
>> data[i] = rand() * fact - max_amplitude;
>> /* make sure that data[i] is within valid range though! */
>> ...
>>}
>
> So in this case, do i declare data[] as a double variable or an interger?
>bademiya wrote:
>
>> Hi.
>>
>> I am trying to generate digital white noise from a bunch of uniform
random
>> numbers. However, when i write my code as belows for random number
>> generation between -1 and 1, it takes a long time to process the data.
>>
>> for(i = 0; i < 5000; i++){
>> data[i] = 2 * (((double)rand() / (double)RAND_MAX) - 0.5);
>> }
>> I understand its due to the fact that Blackfin processors are
fixed-point
>> processors and by declaring the data as double, i am actually using a
lot
>> of processor power.
>
>If the numbers in data[] really must be in the range [-1..+1], then
>double arithmertic is a must. You can speed this up by using
>multiplication instead of division:
>
>double fact = 1.0/RAND_MAX;
>for(i = 0; i < 5000; i++) {
> data[i] = 2 * (((double)rand() * fact - 0.5);
>}
>
>However, I'm very sure that the data go to a DAC with 8 or more bits,
>so an integer division should be good enough for the generation of
noise:
>
>const int dac_bits = 8; /* or 12 or 16 or whatever the documentation
Thanks!
So in this case, do i declare data[] as a double variable or an interger?
Amit.
Reply by Jerry Avins●July 18, 20062006-07-18
Randy Yates wrote:
> bademiya wrote:
>> Hi.
>>
>> I am trying to generate digital white noise from a bunch of uniform random
>> numbers. However, when i write my code as belows for random number
>> generation between -1 and 1, it takes a long time to process the data.
>>
>> for(i = 0; i < 5000; i++){
>> data[i] = 2 * (((double)rand() / (double)RAND_MAX) - 0.5);
>> }
>> I understand its due to the fact that Blackfin processors are fixed-point
>> processors and by declaring the data as double, i am actually using a lot
>> of processor power. I have looked through and realised that i'm actually
>> required to change my data into the fractional format (i.e. Q.15 format).
>> However, i understand that division is not possible in fixed-point
>> processors. How do i resolve this issue?
>
> Google. For example, try "fixed-point division".
Bademiya,
Write a decent (it needn't be excellent) single-precision RNG. A linear
congruential RNG is simple and fast. A standard integer routine will
provide outputs from -1 to (almost)1 if you construe the integer (0 to
65535) output as signed Q.15. To completely avoid DC bias, check for
$FFFF and repeat the call to rand() if you find it. How to design an LC
RNG is at http://tinyurl.com/gz73p. Not all that fit the criteria there
are equally good, so find a recommended set of coefficients if you can.
Jerry
--
Engineering is the art of making what you want from things you can get.
�����������������������������������������������������������������������
Reply by Stefan Reuther●July 18, 20062006-07-18
bademiya wrote:
> I understand its due to the fact that Blackfin processors are fixed-point
> processors and by declaring the data as double, i am actually using a lot
> of processor power. I have looked through and realised that i'm actually
> required to change my data into the fractional format (i.e. Q.15 format).
Fractional format ist just plain integers. 32767 means .999969482421875,
and -32768 means -1.0. So, for fractional format, all you need to do is
generate values between -32768 and +32767.
> However, i understand that division is not possible in fixed-point
> processors. How do i resolve this issue?
You don't need division.
Use a PRNG of your choice (with at least 16 bits output, standard rand()
may only give you 15 bits), and pick a few bits from the inside. Here's
a really simple one:
int32_t seed = 0;
int16_t my_rand() {
seed = 134775813 * seed + 1; // PRNG
return (int16_t) (seed >> 16); // pick upper bits
}
(The magic numbers 134775813 and 1 want to be chosen carefully, the
above ones are stolen from the Turbo Pascal runtime library :-) I know
it works fine for things like shuffling cards, but haven't tried yet how
it sounds.)
If you want smaller range, there's still no need to divide. To obtain a
random number in range [0,N), generate a random number in range
[0,2**B), multiply by N, and shift right B. To generate a random number
between [-N,N), do the same with [-2**B,2**B):
int16_t my_rand_range(int16_t range) {
// returns value between -range (inclusive)
// and +range (exclusive)
return (my_rand() * range) >> 15;
}
"Multiply and shift right 15" is exactly the operation behind a
fractional-mode multiplication (mult_fr1x16 from <fract.h>, if memory
serves me right).
If you keep using doubles, using the ldexp function may also be a win,
but you should measure it first: ldexp is sort-of a floating-point shift
operation, and it is comparatively fast. 'ldexp(my_rand(), -15)' gives
you random numbers from [-1.0, +1.0).
Stefan
Reply by Leon●July 18, 20062006-07-18
bademiya wrote:
> Hi.
>
> I am trying to generate digital white noise from a bunch of uniform random
> numbers. However, when i write my code as belows for random number
> generation between -1 and 1, it takes a long time to process the data.
>
> for(i = 0; i < 5000; i++){
> data[i] = 2 * (((double)rand() / (double)RAND_MAX) - 0.5);
> }
> I understand its due to the fact that Blackfin processors are fixed-point
> processors and by declaring the data as double, i am actually using a lot
> of processor power. I have looked through and realised that i'm actually
> required to change my data into the fractional format (i.e. Q.15 format).
> However, i understand that division is not possible in fixed-point
> processors. How do i resolve this issue?
You can do fixed-point division on the Blackfin. It's not as
straightforward as multiplication, though. It's covered in the
documentation. You'll need to use assembler.
Leon
Reply by Andreas Huennebeck●July 18, 20062006-07-18
bademiya wrote:
> Hi.
>
> I am trying to generate digital white noise from a bunch of uniform random
> numbers. However, when i write my code as belows for random number
> generation between -1 and 1, it takes a long time to process the data.
>
> for(i = 0; i < 5000; i++){
> data[i] = 2 * (((double)rand() / (double)RAND_MAX) - 0.5);
> }
> I understand its due to the fact that Blackfin processors are fixed-point
> processors and by declaring the data as double, i am actually using a lot
> of processor power.
If the numbers in data[] really must be in the range [-1..+1], then
double arithmertic is a must. You can speed this up by using
multiplication instead of division:
double fact = 1.0/RAND_MAX;
for(i = 0; i < 5000; i++) {
data[i] = 2 * (((double)rand() * fact - 0.5);
}
However, I'm very sure that the data go to a DAC with 8 or more bits,
so an integer division should be good enough for the generation of noise:
const int dac_bits = 8; /* or 12 or 16 or whatever the documentation says) */
const int range = 1 << dac_bits;
const int max_amplitude = range / 2;
const int fact = (double)range / (double)RAND_MAX;
for(i = 0; i < 5000; i++) {
data[i] = rand() * fact - max_amplitude;
/* make sure that data[i] is within valid range though! */
...
}
bye
Andreas
--
Andreas H�nnebeck | email: acmh@gmx.de
----- privat ---- | www : http://www.huennebeck-online.de
Fax/Anrufbeantworter: 0721/151-284301
GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc
PGP-Key: http://www.huennebeck-online.de/public_keys/pgp_andreas.asc
Reply by Randy Yates●July 18, 20062006-07-18
bademiya wrote:
> Hi.
>
> I am trying to generate digital white noise from a bunch of uniform random
> numbers. However, when i write my code as belows for random number
> generation between -1 and 1, it takes a long time to process the data.
>
> for(i = 0; i < 5000; i++){
> data[i] = 2 * (((double)rand() / (double)RAND_MAX) - 0.5);
> }
> I understand its due to the fact that Blackfin processors are fixed-point
> processors and by declaring the data as double, i am actually using a lot
> of processor power. I have looked through and realised that i'm actually
> required to change my data into the fractional format (i.e. Q.15 format).
> However, i understand that division is not possible in fixed-point
> processors. How do i resolve this issue?
Google. For example, try "fixed-point division".
--Randy
Reply by bademiya●July 18, 20062006-07-18
Hi.
I am trying to generate digital white noise from a bunch of uniform random
numbers. However, when i write my code as belows for random number
generation between -1 and 1, it takes a long time to process the data.
for(i = 0; i < 5000; i++){
data[i] = 2 * (((double)rand() / (double)RAND_MAX) - 0.5);
}
I understand its due to the fact that Blackfin processors are fixed-point
processors and by declaring the data as double, i am actually using a lot
of processor power. I have looked through and realised that i'm actually
required to change my data into the fractional format (i.e. Q.15 format).
However, i understand that division is not possible in fixed-point
processors. How do i resolve this issue?
Amit.