Sorry for the newbie question... but I'm confused. I'm trying to read the
data from an AIFF file and calculating the RMS value.. but the following
code isn't giving me the correct results. I know the issue is in the way I'm
normalizing the 24 bit values but everything I've tried hasn't provided the
right solution... So thought I'd ask the pros.
The gist of my code is:
-------------------------
CMemFile mf;
unsigned int iBufferSize = 614400;
unsigned int iLoopAmount;
DWORD dwReadAmount;
DWORD dwDataLen;
int iDataSize;
DWORD dwFlip;
double fAccumulator = 0.0;
ULONGLONG iNumSamples = 0L;
:
:
iLoopAmount = dwDataLen % iBufferSize;
dwReadAmount = iLoopAmount/(iDataSize * m_iNoChannels);
:
if (iLoopAmount)
{
mf.Seek(0L, CFile::begin);
m_fSndFile.Read(pBuffer, iLoopAmount); // Read data
from actual file into memfile for speed
mf.Write(pBuffer, iLoopAmount);
mf.Seek(0L, CFile::begin);
for (k = 0; k < dwReadAmount; k++)
{
iValue = 0;
mf.Read(&dwFlip, iDataSize); //
Flip for AIFF
iValue = DXCHG(dwFlip << 8); // iValue
is correct!
iNumSamples++;
double xx = (double)iValue/(double)0x7FFFFF; // I believe
this is where I'm having issues
// I believe I need to normalize the value here
fAccumulator += pow(xx, 2.0);
}
}
double fRMSValue= fAccumulator/iNumSamples;
fRMSValue = sqrt(fRMSValue);
double fRMSasDecibels = 20*log10(fRMSValue);
Which returns the wrong value. As indicated I believe my issue is dealing
with the actual data value. I've tried just using iValue without dividing
it, using
the abs() value.. nothing's giving me the right result. Obviously I'm not
normalizing it correctly.
Thanks for any assistance,
Rail
--
Recording Engineer/Software Developer
Rail Jon Rogut Software
http://www.railjonrogut.com
mailto:rail@railjonrogut.com
Newbie RMS question
Started by ●July 11, 2006
Reply by ●July 11, 20062006-07-11
Rail Jon Rogut wrote:> Sorry for the newbie question... but I'm confused. I'm trying to > read the data from an AIFF file and calculating the RMS value.. > but the following code isn't giving me the correct results. I > know the issue is in the way I'm normalizing the 24 bit values > but everything I've tried hasn't provided the right solution...Is there a trend to the deviation? How do you get the expected outputs? Martin -- Dare to think! --Paracelsus
Reply by ●July 11, 20062006-07-11
I haven't found a trend... I've certainly looked for one.
I created a sine wave AIFF file containing only 44 samples in Pro Tools...
which reports an RMS level of -29.7dB. Sound Forge reports -29.0dB.
The data output from my log file:
File = R:\RMS Test files\Sine -29.7dB rms.aif
Sample = 0001 -- Value: 0 -- Hex = 0
Sample = 0002 -- Value: 752447 -- Hex = b7b3f
Sample = 0003 -- Value: 1489646 -- Hex = 16baee
Sample = 0004 -- Value: 2196657 -- Hex = 2184b1
Sample = 0005 -- Value: 2859152 -- Hex = 2ba090
Sample = 0006 -- Value: 3463707 -- Hex = 34da1b
Sample = 0007 -- Value: 3998069 -- Hex = 3d0175
Sample = 0008 -- Value: 4451409 -- Hex = 43ec51
Sample = 0009 -- Value: 4814542 -- Hex = 4976ce
Sample = 0010 -- Value: 5080107 -- Hex = 4d842b
Sample = 0011 -- Value: 5242724 -- Hex = 4fff64
Sample = 0012 -- Value: 5299096 -- Hex = 50db98
Sample = 0013 -- Value: 5248081 -- Hex = 501451
Sample = 0014 -- Value: 5090714 -- Hex = 4dad9a
Sample = 0015 -- Value: 4830182 -- Hex = 49b3e6
Sample = 0016 -- Value: 4471767 -- Hex = 443bd7
Sample = 0017 -- Value: 4022730 -- Hex = 3d61ca
Sample = 0018 -- Value: 3492173 -- Hex = 35494d
Sample = 0019 -- Value: 2890847 -- Hex = 2c1c5f
Sample = 0020 -- Value: 2230937 -- Hex = 220a99
Sample = 0021 -- Value: 1525817 -- Hex = 174839
Sample = 0022 -- Value: 789776 -- Hex = c0d10
Sample = 0023 -- Value: 37730 -- Hex = 9362
Sample = 0024 -- Value: 16062136 -- Hex = f516b8
Sample = 0025 -- Value: 15323817 -- Hex = e9d2a9
Sample = 0026 -- Value: 14614951 -- Hex = df01a7
Sample = 0027 -- Value: 13949904 -- Hex = d4dbd0
Sample = 0028 -- Value: 13342153 -- Hex = cb95c9
Sample = 0029 -- Value: 12804013 -- Hex = c35fad
Sample = 0030 -- Value: 12346392 -- Hex = bc6418
Sample = 0031 -- Value: 11978561 -- Hex = b6c741
Sample = 0032 -- Value: 11707976 -- Hex = b2a648
Sample = 0033 -- Value: 11540119 -- Hex = b01697
Sample = 0034 -- Value: 11478393 -- Hex = af2579
Sample = 0035 -- Value: 11524048 -- Hex = afd7d0
Sample = 0036 -- Value: 11676158 -- Hex = b229fe
Sample = 0037 -- Value: 11931643 -- Hex = b60ffb
Sample = 0038 -- Value: 12285323 -- Hex = bb758b
Sample = 0039 -- Value: 12730032 -- Hex = c23eb0
Sample = 0040 -- Value: 13256758 -- Hex = ca4836
Sample = 0041 -- Value: 13854826 -- Hex = d3686a
Sample = 0042 -- Value: 14512116 -- Hex = dd6ff4
Sample = 0043 -- Value: 15215309 -- Hex = e82acd
Sample = 0044 -- Value: 15950155 -- Hex = f3614b
My code doesn't approach anything close to -29dB but no constant
proportional difference that I've been able to figure out.
Thanks,
Rail
--
Recording Engineer/Software Developer
Rail Jon Rogut Software
http://www.railjonrogut.com
mailto:rail@railjonrogut.com
"Martin Eisenberg" <martin.eisenberg@udo.edu> wrote in message
news:1152653941.848812@ostenberg.wh.uni-dortmund.de...
> Rail Jon Rogut wrote:
>
>> Sorry for the newbie question... but I'm confused. I'm trying to
>> read the data from an AIFF file and calculating the RMS value..
>> but the following code isn't giving me the correct results. I
>> know the issue is in the way I'm normalizing the 24 bit values
>> but everything I've tried hasn't provided the right solution...
>
> Is there a trend to the deviation? How do you get the expected
> outputs?
>
>
> Martin
>
> --
> Dare to think!
> --Paracelsus
Reply by ●July 11, 20062006-07-11
Rail Jon Rogut wrote:> Sorry for the newbie question... but I'm confused. I'm trying to read the > data from an AIFF file and calculating the RMS value.. but the following > code isn't giving me the correct results. I know the issue is in the way I'm > normalizing the 24 bit values but everything I've tried hasn't provided the > right solution... So thought I'd ask the pros. > > The gist of my code is: > ------------------------- > > CMemFile mf; > > unsigned int iBufferSize = 614400; > > unsigned int iLoopAmount; > > DWORD dwReadAmount; > DWORD dwDataLen; > int iDataSize; > DWORD dwFlip; > > double fAccumulator = 0.0; > ULONGLONG iNumSamples = 0L; > > : > : > > iLoopAmount = dwDataLen % iBufferSize; > dwReadAmount = iLoopAmount/(iDataSize * m_iNoChannels); > > : > > if (iLoopAmount) > { > mf.Seek(0L, CFile::begin); > > m_fSndFile.Read(pBuffer, iLoopAmount); // Read data > from actual file into memfile for speed > > mf.Write(pBuffer, iLoopAmount); > mf.Seek(0L, CFile::begin); > > for (k = 0; k < dwReadAmount; k++) > { > iValue = 0; > > mf.Read(&dwFlip, iDataSize); // > Flip for AIFF > > iValue = DXCHG(dwFlip << 8); // iValue > is correct! > > iNumSamples++; > > double xx = (double)iValue/(double)0x7FFFFF; // I believe > this is where I'm having issues > > // I believe I need to normalize the value here > > fAccumulator += pow(xx, 2.0); > } > } > > double fRMSValue= fAccumulator/iNumSamples; > > fRMSValue = sqrt(fRMSValue); > > double fRMSasDecibels = 20*log10(fRMSValue); > > > Which returns the wrong value. As indicated I believe my issue is dealing > with the actual data value. I've tried just using iValue without dividing > it, using > the abs() value.. nothing's giving me the right result. Obviously I'm not > normalizing it correctly.Do you get the correct sum of squares? The correct mean? The correct square root? All those precede the log whose result is wrong. Knowing where things go wrong will be a big help. Start with a file of a few constants, and work up to more complex sets of numbers. Jerry -- Poke it and watch to see where it wiggles. �����������������������������������������������������������������������
Reply by ●July 11, 20062006-07-11
Well I believe the log calculation can only be one of 2 things depending on
how I normalize the values:
double fRMSasDecibels = 20*log10(fRMSValue);
or
double fRMSasDecibels = 20*log10(fRMSValue/0x7fffff);
neither of which give the correct result -- so the value for fRMSValue is
wrong. fRMSValue I know is calculated correctly as the sum of the squares
divided by the number of samples -- so the error is that the sum of squares
(fAccumulator) is incorrect. The sum of squares rely on the normalization
of the data value.. which is why I think that's where the error exists.
29.7 = 20 * log10(fRMSValue) means fRMSValue = 30.549
29.7 = 20 * log10(fRMSValue/0x7fffff) means fRMSValue = 256265326.347
If I run the code as posted my log file is:
File = R:\RMS Test files\Sine -29.7dB rms.aif
Sample = 0001 -- Value: 0 -- Hex = 0 -- SumOfSq =
0.000000
Sample = 0002 -- Value: 752447 -- Hex = b7b3f -- SumOfSq =
0.008046
Sample = 0003 -- Value: 1489646 -- Hex = 16baee -- SumOfSq =
0.039580
Sample = 0004 -- Value: 2196657 -- Hex = 2184b1 -- SumOfSq =
0.108152
Sample = 0005 -- Value: 2859152 -- Hex = 2ba090 -- SumOfSq =
0.224322
Sample = 0006 -- Value: 3463707 -- Hex = 34da1b -- SumOfSq =
0.394814
Sample = 0007 -- Value: 3998069 -- Hex = 3d0175 -- SumOfSq =
0.621968
Sample = 0008 -- Value: 4451409 -- Hex = 43ec51 -- SumOfSq =
0.903557
Sample = 0009 -- Value: 4814542 -- Hex = 4976ce -- SumOfSq =
1.232962
Sample = 0010 -- Value: 5080107 -- Hex = 4d842b -- SumOfSq =
1.599708
Sample = 0011 -- Value: 5242724 -- Hex = 4fff64 -- SumOfSq =
1.990310
Sample = 0012 -- Value: 5299096 -- Hex = 50db98 -- SumOfSq =
2.389357
Sample = 0013 -- Value: 5248081 -- Hex = 501451 -- SumOfSq =
2.780758
Sample = 0014 -- Value: 5090714 -- Hex = 4dad9a -- SumOfSq =
3.149037
Sample = 0015 -- Value: 4830182 -- Hex = 49b3e6 -- SumOfSq =
3.480586
Sample = 0016 -- Value: 4471767 -- Hex = 443bd7 -- SumOfSq =
3.764756
Sample = 0017 -- Value: 4022730 -- Hex = 3d61ca -- SumOfSq =
3.994721
Sample = 0018 -- Value: 3492173 -- Hex = 35494d -- SumOfSq =
4.168027
Sample = 0019 -- Value: 2890847 -- Hex = 2c1c5f -- SumOfSq =
4.286787
Sample = 0020 -- Value: 2230937 -- Hex = 220a99 -- SumOfSq =
4.357515
Sample = 0021 -- Value: 1525817 -- Hex = 174839 -- SumOfSq =
4.390600
Sample = 0022 -- Value: 789776 -- Hex = c0d10 -- SumOfSq =
4.399464
Sample = 0023 -- Value: 37730 -- Hex = 9362 -- SumOfSq =
4.399484
Sample = 0024 -- Value: 16062136 -- Hex = f516b8 -- SumOfSq =
8.065775
Sample = 0025 -- Value: 15323817 -- Hex = e9d2a9 -- SumOfSq =
11.402759
Sample = 0026 -- Value: 14614951 -- Hex = df01a7 -- SumOfSq =
14.438153
Sample = 0027 -- Value: 13949904 -- Hex = d4dbd0 -- SumOfSq =
17.203584
Sample = 0028 -- Value: 13342153 -- Hex = cb95c9 -- SumOfSq =
19.733302
Sample = 0029 -- Value: 12804013 -- Hex = c35fad -- SumOfSq =
22.063069
Sample = 0030 -- Value: 12346392 -- Hex = bc6418 -- SumOfSq =
24.229278
Sample = 0031 -- Value: 11978561 -- Hex = b6c741 -- SumOfSq =
26.268336
Sample = 0032 -- Value: 11707976 -- Hex = b2a648 -- SumOfSq =
28.216314
Sample = 0033 -- Value: 11540119 -- Hex = b01697 -- SumOfSq =
30.108836
Sample = 0034 -- Value: 11478393 -- Hex = af2579 -- SumOfSq =
31.981166
Sample = 0035 -- Value: 11524048 -- Hex = afd7d0 -- SumOfSq =
33.868420
Sample = 0036 -- Value: 11676158 -- Hex = b229fe -- SumOfSq =
35.805824
Sample = 0037 -- Value: 11931643 -- Hex = b60ffb -- SumOfSq =
37.828941
Sample = 0038 -- Value: 12285323 -- Hex = bb758b -- SumOfSq =
39.973773
Sample = 0039 -- Value: 12730032 -- Hex = c23eb0 -- SumOfSq =
42.276696
Sample = 0040 -- Value: 13256758 -- Hex = ca4836 -- SumOfSq =
44.774135
Sample = 0041 -- Value: 13854826 -- Hex = d3686a -- SumOfSq =
47.501998
Sample = 0042 -- Value: 14512116 -- Hex = dd6ff4 -- SumOfSq =
50.494826
Sample = 0043 -- Value: 15215309 -- Hex = e82acd -- SumOfSq =
53.784719
Sample = 0044 -- Value: 15950155 -- Hex = f3614b -- SumOfSq =
57.400067
SumOfSq is fAccumulator in my code fragment.
fRMSValue = sqrt(fAccumulator/iNumSamples) = 1.142168
20 * log10(fRMSValue) = 1.154597
------------
If I use the alternate double fRMSasDecibels = 20*log10(fRMSValue/0x7fffff)
and don't divide the iValue by 0x7fffff then I get:
File = R:\RMS Test files\Sine -29.7dB rms.aif
Sample = 0001 -- Value: 0 -- Hex = 0 -- SumOfSq =
0.000000
Sample = 0002 -- Value: 752447 -- Hex = b7b3f -- SumOfSq =
566176487809.000000
Sample = 0003 -- Value: 1489646 -- Hex = 16baee -- SumOfSq =
2785221693125.000000
Sample = 0004 -- Value: 2196657 -- Hex = 2184b1 -- SumOfSq =
7610523668774.000000
Sample = 0005 -- Value: 2859152 -- Hex = 2ba090 -- SumOfSq =
15785273827878.000000
Sample = 0006 -- Value: 3463707 -- Hex = 34da1b -- SumOfSq =
27782540009727.000000
Sample = 0007 -- Value: 3998069 -- Hex = 3d0175 -- SumOfSq =
43767095738488.000000
Sample = 0008 -- Value: 4451409 -- Hex = 43ec51 -- SumOfSq =
63582137823769.000000
Sample = 0009 -- Value: 4814542 -- Hex = 4976ce -- SumOfSq =
86761952493533.000000
Sample = 0010 -- Value: 5080107 -- Hex = 4d842b -- SumOfSq =
112569439624982.000000
Sample = 0011 -- Value: 5242724 -- Hex = 4fff64 -- SumOfSq =
140055594565158.000000
Sample = 0012 -- Value: 5299096 -- Hex = 50db98 -- SumOfSq =
168136012982374.000000
Sample = 0013 -- Value: 5248081 -- Hex = 501451 -- SumOfSq =
195678367164935.000000
Sample = 0014 -- Value: 5090714 -- Hex = 4dad9a -- SumOfSq =
221593736194731.000000
Sample = 0015 -- Value: 4830182 -- Hex = 49b3e6 -- SumOfSq =
244924394347855.000000
Sample = 0016 -- Value: 4471767 -- Hex = 443bd7 -- SumOfSq =
264921094450144.000000
Sample = 0017 -- Value: 4022730 -- Hex = 3d61ca -- SumOfSq =
281103451103044.000000
Sample = 0018 -- Value: 3492173 -- Hex = 35494d -- SumOfSq =
293298723364973.000000
Sample = 0019 -- Value: 2890847 -- Hex = 2c1c5f -- SumOfSq =
301655719742382.000000
Sample = 0020 -- Value: 2230937 -- Hex = 220a99 -- SumOfSq =
306632799640351.000000
Sample = 0021 -- Value: 1525817 -- Hex = 174839 -- SumOfSq =
308960917157840.000000
Sample = 0022 -- Value: 789776 -- Hex = c0d10 -- SumOfSq =
309584663288016.000000
Sample = 0023 -- Value: 37730 -- Hex = 9362 -- SumOfSq =
309586086840916.000000
Sample = 0024 -- Value: 16062136 -- Hex = f516b8 -- SumOfSq =
567578299723412.000000
Sample = 0025 -- Value: 15323817 -- Hex = e9d2a9 -- SumOfSq =
802397667172901.000000
Sample = 0026 -- Value: 14614951 -- Hex = df01a7 -- SumOfSq =
1015994459905302.000000
Sample = 0027 -- Value: 13949904 -- Hex = d4dbd0 -- SumOfSq =
1210594281514518.000000
Sample = 0028 -- Value: 13342153 -- Hex = cb95c9 -- SumOfSq =
1388607328189927.000000
Sample = 0029 -- Value: 12804013 -- Hex = c35fad -- SumOfSq =
1552550077094096.000000
Sample = 0030 -- Value: 12346392 -- Hex = bc6418 -- SumOfSq =
1704983472511760.000000
Sample = 0031 -- Value: 11978561 -- Hex = b6c741 -- SumOfSq =
1848469396142481.000000
Sample = 0032 -- Value: 11707976 -- Hex = b2a648 -- SumOfSq =
1985546098159057.000000
Sample = 0033 -- Value: 11540119 -- Hex = b01697 -- SumOfSq =
2118720444693218.000000
Sample = 0034 -- Value: 11478393 -- Hex = af2579 -- SumOfSq =
2250473950555667.000000
Sample = 0035 -- Value: 11524048 -- Hex = afd7d0 -- SumOfSq =
2383277632861971.000000
Sample = 0036 -- Value: 11676158 -- Hex = b229fe -- SumOfSq =
2519610298502935.000000
Sample = 0037 -- Value: 11931643 -- Hex = b60ffb -- SumOfSq =
2661974403182384.000000
Sample = 0038 -- Value: 12285323 -- Hex = bb758b -- SumOfSq =
2812903564396713.000000
Sample = 0039 -- Value: 12730032 -- Hex = c23eb0 -- SumOfSq =
2974957279117737.000000
Sample = 0040 -- Value: 13256758 -- Hex = ca4836 -- SumOfSq =
3150698911788301.000000
Sample = 0041 -- Value: 13854826 -- Hex = d3686a -- SumOfSq =
3342655115278577.000000
Sample = 0042 -- Value: 14512116 -- Hex = dd6ff4 -- SumOfSq =
3553256626076033.000000
Sample = 0043 -- Value: 15215309 -- Hex = e82acd -- SumOfSq =
3784762254041514.000000
Sample = 0044 -- Value: 15950155 -- Hex = f3614b -- SumOfSq =
4039169698565539.000000
sqrt((fAccumulator/iNumSamples)/0x7fffff) = 3308.070735
20 * log10(fRMSValue) = 70.391496
Neither of the above approach the expected result.. so I've tried 2 test
files and looked for a common constant difference between what's expected
and what I achieve and I see no constant I can just plug-in... hence my
dilemma.
I just thought someone here may have previously written an RMS algorith for
24 bit data and would have instantly seen my error.
Thanks for reading.
Rail
--
Recording Engineer/Software Developer
Rail Jon Rogut Software
http://www.railjonrogut.com
mailto:rail@railjonrogut.com
"Jerry Avins" <jya@ieee.org> wrote in message
news:_oWdnWiCOLr72ynZnZ2dnUVZ_r6dnZ2d@rcn.net...
> Rail Jon Rogut wrote:
>> Sorry for the newbie question... but I'm confused. I'm trying to read the
>> data from an AIFF file and calculating the RMS value.. but the following
>> code isn't giving me the correct results. I know the issue is in the way
>> I'm normalizing the 24 bit values but everything I've tried hasn't
>> provided the right solution... So thought I'd ask the pros.
>>
>> The gist of my code is:
>> -------------------------
>>
>> CMemFile mf;
>>
>> unsigned int iBufferSize = 614400;
>>
>> unsigned int iLoopAmount;
>>
>> DWORD dwReadAmount;
>> DWORD dwDataLen;
>> int iDataSize;
>> DWORD dwFlip;
>>
>> double fAccumulator = 0.0;
>> ULONGLONG iNumSamples = 0L;
>>
>> :
>> :
>>
>> iLoopAmount = dwDataLen % iBufferSize;
>> dwReadAmount = iLoopAmount/(iDataSize * m_iNoChannels);
>>
>> :
>>
>> if (iLoopAmount)
>> {
>> mf.Seek(0L, CFile::begin);
>>
>> m_fSndFile.Read(pBuffer, iLoopAmount); // Read
>> data from actual file into memfile for speed
>>
>> mf.Write(pBuffer, iLoopAmount);
>> mf.Seek(0L, CFile::begin);
>>
>> for (k = 0; k < dwReadAmount; k++)
>> {
>> iValue = 0;
>>
>> mf.Read(&dwFlip, iDataSize); //
>> Flip for AIFF
>>
>> iValue = DXCHG(dwFlip << 8); //
>> iValue is correct!
>>
>> iNumSamples++;
>>
>> double xx = (double)iValue/(double)0x7FFFFF; // I believe
>> this is where I'm having issues
>>
>> // I believe I need to normalize the value here
>>
>> fAccumulator += pow(xx, 2.0);
>> }
>> }
>>
>> double fRMSValue= fAccumulator/iNumSamples;
>>
>> fRMSValue = sqrt(fRMSValue);
>>
>> double fRMSasDecibels = 20*log10(fRMSValue);
>>
>>
>> Which returns the wrong value. As indicated I believe my issue is dealing
>> with the actual data value. I've tried just using iValue without dividing
>> it, using
>> the abs() value.. nothing's giving me the right result. Obviously I'm not
>> normalizing it correctly.
>
> Do you get the correct sum of squares? The correct mean? The correct
> square root? All those precede the log whose result is wrong. Knowing
> where things go wrong will be a big help. Start with a file of a few
> constants, and work up to more complex sets of numbers.
>
> Jerry
> --
> Poke it and watch to see where it wiggles.
> �����������������������������������������������������������������������
Reply by ●July 11, 20062006-07-11
Rail Jon Rogut wrote:> Well I believe the log calculation can only be one of 2 things depending on > how I normalize the values: > > double fRMSasDecibels = 20*log10(fRMSValue); > > or > > double fRMSasDecibels = 20*log10(fRMSValue/0x7fffff); > > neither of which give the correct result -- so the value for fRMSValue is > wrong. fRMSValue I know is calculated correctly as the sum of the squares > divided by the number of samples -- so the error is that the sum of squares > (fAccumulator) is incorrect. The sum of squares rely on the normalization > of the data value.. which is why I think that's where the error exists.... I'm not going to follow through your code. Why do you need to normalize? What do you get when run the routine on 10 values all the same, and each a perfect square? Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by ●July 12, 20062006-07-12
Rail Jon Rogut wrote:> I created a sine wave AIFF file containing only 44 samples in > Pro Tools... which reports an RMS level of -29.7dB. Sound Forge > reports -29.0dB.That's interesting -- I don't have a 24-bit tool at hand, but when I truncate your numbers to 16 bits Sound Forge 4.5 reports -6.98 dB which I presume is also basically your code's result. The SF help notes a change in RMS reference from an earlier version; maybe your tools' docs also describe what the display means? Well, you've probably already looked. Sorry I can't point to anything concrete.> My code doesn't approach anything close to -29dB but no constant > proportional difference that I've been able to figure out.So the difference varies between test files? Martin -- Quidquid latine scriptum sit, altum viditur.
Reply by ●July 12, 20062006-07-12
Hi Rail, I have several comments but the gist is this: 1) you have made some miscalculations, and 2) even if you correct your calculations, the signal you've provided is not anywhere near -30 dBFS. See below. Rail Jon Rogut wrote:> Well I believe the log calculation can only be one of 2 things depending on > how I normalize the values: > > double fRMSasDecibels = 20*log10(fRMSValue); > > or > > double fRMSasDecibels = 20*log10(fRMSValue/0x7fffff); > > neither of which give the correct result -- so the value for fRMSValue is > wrong. fRMSValue I know is calculated correctly as the sum of the squares > divided by the number of samplesFirst point: DECIBELS ALWAYS REPRESENT POWER RATIOS. This is universally, eternally true. Memorize it now and you will greatly simplify everything associated with decibels for the rest of your life. So the reason that is stated is that the label "fRMSasDecibels" implies you're trying to express a voltage (which RMS implies) as dB, and you can't - you can only express power, or a ratio of powers, as dB. Now that's not to say you can compute the power FROM the voltage, but the key, fundamental units you're working with are watts and not volts. Finally, what you stated in words in the last sentence is the *mean-square* value, i.e., the power, and you're confusing power with volts in your equation. double fRMSasDecibels = 20*log10(fRMSValue/0x7fffff); should be double dbFS = 10*log10(fMSValue/((0x7fffff)^2 / 2)); If you correct these I think you'll get the right answer, which is -3.99 dBFS. I wrote a little Octave (it will probably run in Matlab too) file to operate on the data you provided and compute dBFS in two different ways - one using the mean-square value and one using the maximum value in the signal (assuming a sinusoidal shape). The m-file, analyze.m, and your sine data, sine.dat, are included at the end of this message. The result of the file is: octave:196> analyze; Mean-Square Value : 14071983365478.613281 dBFS - Mean-Square Method: -3.979945 dBFS - Maximum Method : -3.989762 Martin's value of -6.98 dB is 3 dB higher because his software is computing the value relative to a full-scale square wave power, while my computations are relative to a full-scale sine wave power. Hope this helps. --Randy **************** BEG analyze.m **************** function [y,MS,dBMS,dBMax] = analyze %function [y,MS,dBMS,dBMax] = analyze fid=fopen('sine.dat','rt'); n = 1; [ystr,N] = fscanf(fid, '%s', 1); while (N ~= 0) y(n) = hex2dec(ystr); if y(n) > 2^23 y(n) = y(n) - 2^24; end; n = n + 1; [ystr,N] = fscanf(fid, '%s', 1); end fclose(fid); plot(y); MS = sum(y.^2)/length(y); dBMS = 10*log10(MS/(((2^23)^2)/2)); dBMax = 20*log10(max(y)/2^23); printf('Mean-Square Value : %f\n', MS); printf('dBFS - Mean-Square Method: %f\n',dBMS); printf('dBFS - Maximum Method : %f\n',dBMax); **************** END analyze.m **************** **************** BEG sine.dat **************** 0 b7b3f 16baee 2184b1 2ba090 34da1b 3d0175 43ec51 4976ce 4d842b 4fff64 50db98 501451 4dad9a 49b3e6 443bd7 3d61ca 35494d 2c1c5f 220a99 174839 c0d10 9362 f516b8 e9d2a9 df01a7 d4dbd0 cb95c9 c35fad bc6418 b6c741 b2a648 b01697 af2579 afd7d0 b229fe b60ffb bb758b c23eb0 ca4836 d3686a dd6ff4 e82acd f3614b **************** END sine.dat ****************
Reply by ●July 12, 20062006-07-12
Randy Yates wrote:> [...] > Now that's not to say you can compute the power FROM the voltage,^^^ can't Arrghh! I should have said "can't"!! --Randy
Reply by ●July 13, 20062006-07-13
Randy Yates wrote: (snip)> First point: DECIBELS ALWAYS REPRESENT POWER RATIOS. This is > universally, eternally true. Memorize it now and you will greatly > simplify everything associated with decibels for the rest of your > life.While this is 100% true, it doesn't seem to stop people from referencing 0dB to a voltage, given a known source impedance. The OP could have used 10*log10() without the square root, instead of 20*log10() after the square root. -- glen






