Reply
 
Thread Tools Display Modes
  #1   Report Post  
genlock
 
Posts: n/a
Default Manipulate amplitude of 24 bit audio by 1dBFS or 6dBFS

Hi,

I am working on a project where the output is a 24 bit audio signal.
I am using an FPGA chip to generate this audio signal.
The input to the FPGA is a frequency value ( anywhere between 400hz to
10,000hz).
Inside the FPGA, the frequency is converted to its amplitude by giving
it to a sine look up table.
The output 'A'is then manipulated in such a way( dividing it by 2)
that the amplitude increments by a constant value ( for eg: 6 dBFS)
The output 'A' is manipulated and given out of the FPGA as a serial
data ( 24 bits)
This 24 bit audio ouptut seems to have the correct frequency
information.

What I would like to know is..if this method is correct:that by
dividing this output 'A' by a constant value 2, does it give a change
of 6dBFS

If so, would dividing the 'A' by 1.122 give me a change of 1dBFS?

Or is there any other logic behind this?

Any kind of help would be highly appreciated.

Thankyou

  #2   Report Post  
Mark
 
Posts: n/a
Default

yes

dB = 20 * log10 (x)

where x is the voltage ratio

techncailly that is dB which is a relative term.

dBFS is dB relative to full scale.

Mark


Mark

  #3   Report Post  
genlock
 
Posts: n/a
Default

Hi Mark,
Thankyou for replying.

Yes I have come across this relationship between dB and voltage ratio.

I have also come across this formula:

dB= 20 * log 10 ( x/1677216) for a 24 bit

where 2 ^ 24 = 1677216


So using this formula, I am able to calculate the dB value for any
given bit value

What I would like to know is...that lets say a particulat 24 bit value
"X" represents -k dB

What can be done to "X" in order to change the amplitude by a constant
value ( for eg: 1 DB)

I have come across something like this over the net:

Dividing the 24 bit audio by 2 would cause a 6dB change. Is this
correct?

Thankyou

  #4   Report Post  
Mark
 
Posts: n/a
Default


Yes I have come across this relationship between dB and voltage

ratio.

I have also come across this formula:

dB= 20 * log 10 ( x/1677216) for a 24 bit

where 2 ^ 24 = 1677216


I would think it would be 2^23 = 8388608 becasue one bit is the sighn
bit (but I'm not sure about the standard representation used in 24 bit
sytems)



So using this formula, I am able to calculate the dB value for any
given bit value

Yes .. dB relative to full scale. You are just expressing the volatge
ratio relative to full scale in dB


What I would like to know is...that lets say a particulat 24 bit

value
"X" represents -k dB

What can be done to "X" in order to change the amplitude by a

constant
value ( for eg: 1 DB)


given the dB value, you determine the volatage ratio using

x = 10^(dB/20)

for example
if dB = 1
then x= 1.122
so if you multiply by 1.122 that is increasing the signal by 1 dB
if you divide by 1.122, that is reducing the signal by 1 dB





I have come across something like this over the net:

Dividing the 24 bit audio by 2 would cause a 6dB change. Is this
correct?


x=10^(dB/20)
if dB = 6
then x = 1.9952 ~=2 yes.

or

x=10^(dB/20)
if dB = -6
then x = 0.501 ~=0.5

of course dividing by 2 is the same as multiplyting by 0.5.

These relative change formulas are true for any amount of bits. It is
only when you want dBFS do you need to know how many bits you are using
and what FULL SCALE is.



Thankyou


You're welcome

Mark

  #5   Report Post  
anahata
 
Posts: n/a
Default

genlock wrote:

So using this formula, I am able to calculate the dB value for any
given bit value

What I would like to know is...that lets say a particulat 24 bit value
"X" represents -k dB

What can be done to "X" in order to change the amplitude by a constant
value ( for eg: 1 DB)


If I understand your question correctly...
A 1 dB change is a ratio of 2 to the power 1/20 = 1.035264924

So multiply the amplitude by that value N times in succession for +N dB
and divide the amplitude by that N times in succession for -N dB

Or in general for a N dB increase multiply by 2 to the power (N / 20)
(and for a decrease N is negative and that formula still works)

--
Anahata
-+- http://www.treewind.co.uk
Home: 01638 720444 Mob: 07976 263827


  #6   Report Post  
genlock
 
Posts: n/a
Default

Thanks Mark and Anahata,

What I want to do is vary the audio amplitude from 0dBFS to -30 dBFS in

increments of 1 dB....


The audio amplitude is represented by a 24 bit binary value


This is the output of the FPGA


The input to the FPGA is the frequency information


Whats happening inside the FPGA is that the frequency is converted to
its amplitude


This amplitude value is given to a variable "sample" which is 24 bits


When sample is taken as the 24 bit output, its showing a value of 0dbFS



What manipulation should I do to this "sample" to make it change in
steps of 1?


thankyou

  #7   Report Post  
Ben Bradley
 
Posts: n/a
Default

I don't know what you're selling, but I'm leaving r.a.m in the
crosspost just in case...

In rec.audio.marketplace,rec.audio.pro, on 1 Apr 2005 07:52:06 -0800,
"genlock" wrote:

Hi Mark,
Thankyou for replying.

Yes I have come across this relationship between dB and voltage ratio.

I have also come across this formula:

dB= 20 * log 10 ( x/1677216) for a 24 bit

where 2 ^ 24 = 1677216


So using this formula, I am able to calculate the dB value for any
given bit value

What I would like to know is...that lets say a particulat 24 bit value
"X" represents -k dB


In that case it would be -k dBFS. as it's a dB measurement relative
to the Full Scale value that can be represented as a digital value, in
this case a 24-bit number.

What can be done to "X" in order to change the amplitude by a constant
value ( for eg: 1 DB)


Do some algebra to solve your formula for X. Then you can put in a
dBFS value (which will be less than or equal to 0) and get a value for
X.
Okay, you twisted my arm:

X = (10 ^ (dBFS/20)) * 1677216


I have come across something like this over the net:

Dividing the 24 bit audio by 2 would cause a 6dB change. Is this
correct?


Let's take your original formula and put in 1677216 for x:
dBFS = 20 * log 10 ( x/1677216) for a 24 bit

dBFS = 20 * log 10 ( 1677216/1677216)

dBFS = 0

Divide the 1677216 in the numerator by two and do it again:

dBFS= 20 * log 10 ( 838608/1677216)

dBFS = -6.020599913

So, dividing the numeric value (which as someone else mentioned
represents a voltage) by 2 (or equivalently in binary, shifting one
bit to the right) gives a relative change of 6dB. The answer to ten
significant figures is 6.020599914 and is of course more accurate and
precise, but for most purposes it's fine to just round it to 6.

To check the formula I gave above for X, I'll out in -6 which
should give a number slightly greater than 838608 (for a ratio to full
scale slightly greater than 1/2).

X = (10 ^ (-6/20)) * 1677216

X = 840599.24723

Thankyou


If you have more questions, you will get the best response in
comp.dsp.

-----
http://mindspring.com/~benbradley
  #8   Report Post  
genlock
 
Posts: n/a
Default

So what you are saying is by just choosing the value of X, we can get
the desired dBFS output


As in the example you showed , taking X= 838608...we get the output as
-6dBFS


When I use this technique inside the FPGA, the output 24 bit doesnt
seem to have the right information

whats happening is that:

Frequency information is given as the input to the FPGA

Inside the FPGA, this is fed into a sine conversion look up
table....that gives out an output of 24 bits

Lets name that sample

Then this 24 bit sample is shifted right to get the output as -6dBFS

The shift right seems to be working fine

When I try to divide this 24 bit sample with the value 1.122..it should
be giving me an output of -1dBFS

Instead I am getting a random value no where close to the correct
values

Is this because the operation to be done is not exactly a division ?

Do you have any idea about this?

I would really appreciate it

Thankyou

  #9   Report Post  
Mark
 
Posts: n/a
Default

Is the hardware that does the divide by 1.122 working correctly?

Dividing (the voltage) by 1.122 should be the same as reducing the
signal by 1dB.

Sounds like there is a problem with your divide hardware.

Are the word formats correct?

Mark

  #10   Report Post  
Scott Dorsey
 
Posts: n/a
Default

genlock wrote:

Then this 24 bit sample is shifted right to get the output as -6dBFS

The shift right seems to be working fine

When I try to divide this 24 bit sample with the value 1.122..it should
be giving me an output of -1dBFS


What if you use the same divide operation, but give it 2 as the divisor?

Instead I am getting a random value no where close to the correct
values

Is this because the operation to be done is not exactly a division ?


No, I think your divide is broken. Try dividing by some easy values.
--scott

--
"C'est un Nagra. C'est suisse, et tres, tres precis."


  #11   Report Post  
genlock
 
Posts: n/a
Default

The divide operation is working fine...What I mean to say is that the
hardware that does the divide is working correctly

Its just that the right shift that is done in case of -6dBFS is not
exactly doing a right shift

What its doing is as follows:

sample for 0dBFS

sample (23) & sample(23 downto 1) for -6dBFS

So as u can see, its retaining the 23rd bit as the MSB and shifting the
23 to 1 bits to the right

What is the significance of retaining this 23rd bit every time

For instance, in the case of -12dBFS its as follows:

sample(23) & sample(23) & sample(23 downto 2)

So I am thinking that maybe its not exactly a division operation

That could be the reason why I am gettting random values when I do a
division by 1.122 for -1dBFS

Any ideas about this?

Thankyou

  #12   Report Post  
Ben Bradley
 
Posts: n/a
Default

On 1 Apr 2005 12:19:12 -0800, "genlock" wrote:

So what you are saying is by just choosing the value of X, we can get
the desired dBFS output


As in the example you showed , taking X= 838608...we get the output as
-6dBFS


When I use this technique inside the FPGA, the output 24 bit doesnt
seem to have the right information

whats happening is that:

Frequency information is given as the input to the FPGA

Inside the FPGA, this is fed into a sine conversion look up
table....that gives out an output of 24 bits

Lets name that sample

Then this 24 bit sample is shifted right to get the output as -6dBFS

The shift right seems to be working fine


Shifting is effectively, for this application, multiplication by
powers of 2. Shifting right one bit is multiplying by 0.5, or -6dB.
Shifting right two bits is multiplying by 0.25, or -12dB.
If 6dB steps are good enough, then shifting will be all you need.

When I try to divide this 24 bit sample with the value 1.122..it should
be giving me an output of -1dBFS


That would work fine if your divide were for values of type float
in a C program on a general-purpose desktop PC, but I doubt you want
to stick something into an FPGA to do floating point just to handle
this one operation, especially when it's not neccesary.
As others say, there's probably something wrong with the divide,
but dividing is the wrong function to use anyway when you can multiply
by the reciprocal.
So on't do a divide. Do a multiply. Have a 24 bit word, call it
amplitude. Multiply amplitude by sample, and you'll get a 48-bit
product. Take the high 24 bits of this product, and use this as your
final output value.
This is effectively fixed-point arithmetic, where the 24 bit values
have a binary point at the left, and represent numbers between -1 and
1 (exclusively). It's real useful for doing fractional math with
integer operations.
If you can eliminate the part of the multiply that generates the
lower 24 bit word, you can save some circuitry in the FPGA, but that's
just some optional optimization.

Take the value 1.122. get its reciprocal (you may want to use a
more precise value than those four significant digits, OTOH, is it
that critical that your outputs be within a small fraction of the dB
value you claim it to be? You decide), which to four figures is .8913.
Multiply this by the max 24 bit value, 16777216, and you get
14951854.8992, or you can just truncate it to 14951854. This will be
your 24-bit amplitude value to multiply against the sine table values,
as instructed above, to give an output of -1dBFS.
And of course that only works as-is for the first 180 degrees of
the sinewave, I presume you're handling the sign and all for the whole
360 degrees.

Instead I am getting a random value no where close to the correct
values

Is this because the operation to be done is not exactly a division ?

Do you have any idea about this?

I would really appreciate it

Thankyou


-----
http://mindspring.com/~benbradley
  #13   Report Post  
genlock
 
Posts: n/a
Default

Hi Ben,

I tried doing exactly what you have mentioned here above.....

I tried multiplying instead of dividing

Still the output doesnt give me the correct values

I am also losing the frequency information when I connect the output of
the FPGA to the audio measurement set.

The frequency information isnt lost when I am doing the shift operation
in case of -6dBFS increments

Thats the reason why I was wondering if something else is being done in
case of -6dBFS coz that seems to be giving fine outputs( when seen in
the audio measurement set)

Do you any idea about dither?

Should I do some dithering to the truncated 24 bits before I could give
it as the output

Lemme know if you have some ideas abt this.

I appreciate you helping me out.

Thankyou .

  #14   Report Post  
Scott Dorsey
 
Posts: n/a
Default

genlock wrote:

So as u can see, its retaining the 23rd bit as the MSB and shifting the
23 to 1 bits to the right

What is the significance of retaining this 23rd bit every time


You are doing twos complement arithmetic. The top bit is the sign.

When you divide, you need also to be using twos complement and not just
treating it like an unsigned int.
--scott
--
"C'est un Nagra. C'est suisse, et tres, tres precis."
  #15   Report Post  
genlock
 
Posts: n/a
Default

Are you saying that I need to first divide/Multiply and then get the
2's complement of that...and give that as the output?

Correct me if I am wrong

Or do you mean to say that I should get the 2's complement of the
"sample" before I divide/multiply it?

Thankyou



  #16   Report Post  
Michael Putrino
 
Posts: n/a
Default


"genlock" wrote in message
oups.com...
Hi Ben,

I tried doing exactly what you have mentioned here above.....

I tried multiplying instead of dividing

Still the output doesnt give me the correct values

I am also losing the frequency information when I connect the output of
the FPGA to the audio measurement set.

The frequency information isnt lost when I am doing the shift operation
in case of -6dBFS increments

Thats the reason why I was wondering if something else is being done in
case of -6dBFS coz that seems to be giving fine outputs( when seen in
the audio measurement set)

Do you any idea about dither?

Should I do some dithering to the truncated 24 bits before I could give
it as the output

Lemme know if you have some ideas abt this.

I appreciate you helping me out.

Thankyou .


Are you doing two-s-complement math? Audio data is represented in
two's-complement format.

Mike P.


  #17   Report Post  
genlock
 
Posts: n/a
Default

Hi,
I am not doing 2's complement math.

The only place where the 2's complement is taking place is as follows:

Inside the FPGA, the input frequency is given to a value "theta"

We then calculate x = theta* ( 2pi/2 ^ theta_width)[ theta_width is 10
bits here]

We then calculate sin (x) [ I think this is in 2's complement form]

this sin(x) is given to "sample" [24 bits wide]

Sample is then shifted right in the following way:

sample (23) & sample (23 downto 1) for -6 dBFS [ the 23rd bit of sample
is concatenated with 23 to 1 bits of sample ]

This seems to work right and gives the correct output

But when I do this:

Multiply sample with 1/1.122 to get -1 dBFS , I dont get the correct
output

I am clearly losing some information since shifting right can be done
only if we want to divide/multiply by 2.

Thanks

  #18   Report Post  
Scott Dorsey
 
Posts: n/a
Default

genlock wrote:
Are you saying that I need to first divide/Multiply and then get the
2's complement of that...and give that as the output?


No, you need to use the twos-complement signed division operation. You are
multiplying signed ints, not unsigned ints.

If you really want to, you can shift left, preserve the sign, do your
division with an unsigned word, then shift right and restore the sign.
That's at least two machine cycles at minimum, though.
--scott

--
"C'est un Nagra. C'est suisse, et tres, tres precis."
  #19   Report Post  
genlock
 
Posts: n/a
Default

Shifting left and shifting right is going to multiply and divide it by
2

what I would want to do is by the value 1.122

So I must go in for twos-complement signed division operation then?

Am I right

Thankyou

  #20   Report Post  
Scott Dorsey
 
Posts: n/a
Default

genlock wrote:
I am not doing 2's complement math.


Yes. You should be, because the output you're producing is a signed int.
At least, it SHOULD be one if it's going into an S-PDIF device.
--scott
--
"C'est un Nagra. C'est suisse, et tres, tres precis."


  #21   Report Post  
Scott Dorsey
 
Posts: n/a
Default

genlock wrote:
Shifting left and shifting right is going to multiply and divide it by
2


Right, but you don't care about that. What you want to do is to shift
the sign off, store it, and then shift it back and restore the sign.
Multiplying by 2 is a side-effect but one you don't really care much about.

Another way of doing this would be to AND with a mask that preserved only
the top bit, then AND with a mask that cleared the top bit, do the unsigned
math, check for overflow, then OR the sign back on. That wastes a good dozen
cycles, though.

If your processor doesn't have signed operations, the shift-and-work-with
twice-the-value trick will save a lot of cycles.

what I would want to do is by the value 1.122

So I must go in for twos-complement signed division operation then?


If you are multiplying a signed int, you need to be using the signed
division instruction. Have you ever programmed in assembler before?
--scott

--
"C'est un Nagra. C'est suisse, et tres, tres precis."
  #22   Report Post  
Logan Shaw
 
Posts: n/a
Default

genlock wrote:
Are you saying that I need to first divide/Multiply and then get the
2's complement of that...and give that as the output?

Correct me if I am wrong

Or do you mean to say that I should get the 2's complement of the
"sample" before I divide/multiply it?


I haven't been following the thread, but I'm pretty sure what
he's saying is that you need to use a multiply or divide instruction
that knows it's operating on a two's-complement number.

Let me use four-bit integers as an example.

Let's say you have the value 1100. 10000 - 1100 == 0100, so that
means that 1100 == -4.

Let's say you want to divide 1100 (-4) by 2. The result should
be -2, right? That means 1100 div 0010 == 1110. (1110 == 2
because 10000 - 1110 == 0010.)

But let's say you used an unsigned division operator to divide by
2 instead. Then you would just be shifting right one position
and filling the left with zeros. That gives you a different
answer.

The point is, signed division and unsigned division are two
distinct operations. If you call the these operations div.s and
div.u (respectively), then you can say:

1100 div.s 0010 == 1110 (-4 / 2 == -2)
1100 div.u 0010 == 0110 (12 / 2 == 6)

They don't always just differ in the leftmost bit either. For
example:

1100 div.s 0100 == 1111 (-4 / 4 == -1)
1100 div.u 0100 == 0011 (12 / 4 == 3)

Another way of looking at this is that two's-complement uses a
particular "region" of the (discrete) number line differently:

bit string unsigned val two's-complement val
---------- ------------ --------------------
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 -8
1001 9 -7
1010 10 -6
1011 11 -5
1100 12 -4
1101 13 -3
1110 14 -2
1111 15 -1

These numbers have the following property:

(twos-complement-value (some-N-bit-quantity)) mod 2^N
== (unsigned_int_value (the-same-N-bit-quantity)) mod 2^N

BUT, that doesn't mean they have the same division or multiplcation
operators. (However, it DOES mean they have the same addition and
subtraction operators!)

Hope that helps.

- Logan
  #23   Report Post  
Ben Bradley
 
Posts: n/a
Default

On 1 Apr 2005 14:06:29 -0800, "genlock" wrote:

Hi Ben,

I tried doing exactly what you have mentioned here above.....

I tried multiplying instead of dividing

Still the output doesnt give me the correct values


I agree with the others, you should be doing signed arithmetic.

I am also losing the frequency information when I connect the output of
the FPGA to the audio measurement set.

The frequency information isnt lost when I am doing the shift operation
in case of -6dBFS increments


If the output isn't giving the correct values, you probably won't
be able to read a good frequency output.

Thats the reason why I was wondering if something else is being done in
case of -6dBFS coz that seems to be giving fine outputs( when seen in
the audio measurement set)

Do you any idea about dither?


Dither can take something that's already working and make it
better. It crossed my mind to say something about dither, but with 24
bits the residual distortion is already so low you almost certainly
don't need dither. If you want to decrease distortion to
near-theoretically low levels, you would probably do better to use a
larger sine table and/or do linear interpolation.

But if you want to learn about dither (you may need to use it in
other systems), go to http://digido.com and click on articles, then
dither article.

Should I do some dithering to the truncated 24 bits before I could give
it as the output

Lemme know if you have some ideas abt this.

I appreciate you helping me out.

Thankyou .


-----
http://mindspring.com/~benbradley
Reply
Thread Tools
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
common mode rejection vs. crosstalk xy Pro Audio 385 December 29th 04 12:00 AM
Artists cut out the record biz [email protected] Pro Audio 64 July 9th 04 10:02 PM


All times are GMT +1. The time now is 04:55 PM.

Powered by: vBulletin
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright ©2004-2024 AudioBanter.com.
The comments are property of their posters.
 

About Us

"It's about Audio and hi-fi"