VS 2015, x64, and Code Cleanup

Building and customizing Audacity from the source code.

If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by Robert J. H. » Tue Jan 26, 2016 6:12 am

My opinion is the same as Henric's. White Gaussian noise should definitely be included as it is a better model for real world noise than uniformly distributed one.
Also, the Rms is much lower, ever made a jump out of your seat because of accidentely hitting play on a 0 dB noise track?
I always try to use Gaussian noise for plugin testing, by summing up 20 noise signals.
See also http://www.dspguru.com/dsp/howtos/how-t ... sian-noise.

There's also some code here on the forum that renders the distribution of sample values into an audible histogram (left to right panning) - perhaps in the topic "Study in pink".

Robert
Robert J. H.
 
Posts: 1813
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 7

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by henric » Tue Jan 26, 2016 7:59 pm

Robert J. H. wrote:My opinion is the same as Henric's. White Gaussian noise should definitely be included as it is a better model for real world noise than uniformly distributed one.
Also, the Rms is much lower, ever made a jump out of your seat because of accidentely hitting play on a 0 dB noise track?
I always try to use Gaussian noise for plugin testing, by summing up 20 noise signals.
See also http://www.dspguru.com/dsp/howtos/how-t ... sian-noise.


As long as one has the right C++11 features available, generating uniform or Gaussian noise is trivial. I used the kGaussian case below, added to src/effects/Noise.cpp, to generate the attachment in my earlier post. std::normal_distribution<> is part of the standard library.

Code: Select all
#include <random>
...
   std::mt19937 rng;
...
   case kGaussian:
   {
      // The variance of our uniform distribution is (-mAmp - mAmp)^2 / 12.
      // Adjust the amplitude to to give the same RMS ( (-1 - 1)^2 / 12 = 4/12 = 1/3).
      const double uniformToNormal = sqrt(1 / 3.0);

      std::normal_distribution<float> gaussian(0, mAmp * uniformToNormal);

      for (sampleCount i = 0; i < size; i++)
      {
         buffer[i] = gaussian(rng);
      }

      break;
   }


This would generate a uniform distribution with the same Mersenne Twister generator.
Code: Select all
      std::uniform_real_distribution<float> uniform{ float(-mAmp), float(mAmp) };

      for (sampleCount i = 0; i < size; i++)
      {
         buffer[i] = uniform(rng);
      }
henric
 
Posts: 31
Joined: Sun Jan 17, 2016 9:12 pm
Operating System: Windows 10

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by steve » Tue Jan 26, 2016 8:49 pm

henric wrote:As long as one has the right C++11 features available,

We're not yet using C++11, though that will come eventually.

Have you checked to see if the White noise generated on Windows really is only 15-bit?
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46814
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by henric » Tue Jan 26, 2016 9:33 pm

steve wrote:
henric wrote:Since there are only 2^15 such values, there is no way the Noise generator can generate more than 1/512 of the possible values for 24-bit PCM or float (roughly) waveforms.

I wasn't aware that the Windows version was quite as "bad" as it is, though to put this into proportion, it is only one bit worse than "CD quality".

Yes, you're right. I'd characterize it more as, "borderline and possibly misleading," than "broken". Where by "misleading", I mean that someone using a generated waveform might not expect it to have a bunch of missing codes.

steve wrote:Are you certain that Noise.cpp is using std::rand() and not a WxWidgets version of rand()?

Yes, I was poking about in the guts of things trying to find if "srand()" was getting called (yes it is: DirManager calls it in it's constructor). You can put a breakpoint on the MS CRT rand() or step into it (you may need to enable the Disassembly window and do the "Step Into" there).

steve wrote:I can't find any documentation for there being a wx version, but I've just tested the "white noise", with amplitude 1.0 (0 dB) on a Windows machine, and the samples appear to be 24-bit values (and 30-bit on Linux).

For reference, the Noise.cpp code looks like this:
Code: Select all
   float div = ((float)RAND_MAX) / 2.0f;
...
   case kWhite: // white
      for (sampleCount i = 0; i < size; i++)
      {
         buffer[i] = mAmp * ((rand() / div) - 1.0f);
      }
      break;

On Windows, the generator has been the same since the dawn of time and RAND_MAX is 0x7fff (the define in stdlib.h). It looks something like this:
Code: Select all
// Returns a pseudorandom number in the range [0,32767].
extern "C" int __cdecl rand()
{
    __acrt_ptd* const ptd = __acrt_getptd();

    ptd->_rand_state = ptd->_rand_state * 214013 + 2531011;
    return (ptd->_rand_state >> 16) & RAND_MAX;
}

In the disassembly, the last thing it does before restoring the stack pointer and returning is:
Code: Select all
and         eax,7FFFh

Aside: This is the same generator used in Free Cell.

The code in Noise.cpp scales things from rand()'s 0-32767 to -mAmp to +mAmp, but since there are only 2^15 possible inputs ("rand()" is only called once), there cannot be more than 2^15 possible outputs.

steve wrote:
henric wrote:The attached has three different kinds of white noise that all look the same on the "Plot Spectrum" page. They also sound alike to my tin ears, but they look very, very different in the time domain (zoom in or look at a histogram). Note that the "Binary" track only has two different amplitudes, with a 4:1 bias towards one of the values.

Yes, we could have any number of options for different statistical distributions. I don't think that there is sufficient demand to include such options in the standard release version of Audacity, though it could be interesting as an optional plug-in.

I hear you. I'm not sure much more than Uniform and Normal/Gaussian would be reasonable for a "noise" generator versus a more general syth. The "Binary" track was just there as an example of something that is both "white noise" and useless for any practical purpose. Besides, stray too far from the technical sense of the word "noise" and one starts to intrude on barking dogs and one or another top 40 hit.
henric
 
Posts: 31
Joined: Sun Jan 17, 2016 9:12 pm
Operating System: Windows 10

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by Robert J. H. » Wed Jan 27, 2016 4:07 am

henric wrote:
Robert J. H. wrote:My opinion is the same as Henric's. White Gaussian noise should definitely be included as it is a better model for real world noise than uniformly distributed one.
Also, the Rms is much lower, ever made a jump out of your seat because of accidentely hitting play on a 0 dB noise track?
I always try to use Gaussian noise for plugin testing, by summing up 20 noise signals.
See also http://www.dspguru.com/dsp/howtos/how-t ... sian-noise.


As long as one has the right C++11 features available, generating uniform or Gaussian noise is trivial. I used the kGaussian case below, added to src/effects/Noise.cpp, to generate the attachment in my earlier post. std::normal_distribution<> is part of the standard library.

Code: Select all
#include <random>
...
   std::mt19937 rng;
...
   case kGaussian:
   {
      // The variance of our uniform distribution is (-mAmp - mAmp)^2 / 12.
      // Adjust the amplitude to to give the same RMS ( (-1 - 1)^2 / 12 = 4/12 = 1/3).
      const double uniformToNormal = sqrt(1 / 3.0);

      std::normal_distribution<float> gaussian(0, mAmp * uniformToNormal);

      for (sampleCount i = 0; i < size; i++)
      {
         buffer[i] = gaussian(rng);
      }

      break;
   }


This would generate a uniform distribution with the same Mersenne Twister generator.
Code: Select all
      std::uniform_real_distribution<float> uniform{ float(-mAmp), float(mAmp) };

      for (sampleCount i = 0; i < size; i++)
      {
         buffer[i] = uniform(rng);
      }


Sorry, I've been talking about the noise creation in Nyquist.

Using my "Bit-Depth Determination" plug-in, the Audacity noise is reported as 26-bit integer and the Nyquist noise as 32-bit integer.
There is certainly some scaling in the background, but the indication is clear.
Robert J. H.
 
Posts: 1813
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 7

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by henric » Wed Jan 27, 2016 8:50 am

Robert J. H wrote:Sorry, I've been talking about the noise creation in Nyquist.


You are referring to the noise function? It calls "snd-white", which is implemented in white.c with,
Code: Select all
*out_ptr_reg++ = (sample_type) (rand() * rand_scale - 1.0);
where "rand_scale" is defined as,
Code: Select all
#define rand_scale (2.0/RAND_MAX)
in white.h.
This gets us back to our old friend "rand()".

If one wanted to change this, using a better RNG at least on Windows and adding a new function to do Gaussian noise, the right place to do so would probably be upstream in the original Nyquist library. Adding a "snd-whiten" or "snd-whiteg" function wouldn't be all that intrusive to the Nyquist code; I think adding a line to sndfnintptrs.h would do it. Still, upstream is better.

There seems to be a distributions.lsp with a "gaussian-dist", but if it returns a single value at a time, it might be a bit slow for generating a track.
henric
 
Posts: 31
Joined: Sun Jan 17, 2016 9:12 pm
Operating System: Windows 10

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by steve » Wed Jan 27, 2016 11:32 am

In a white noise plug-in, would it be useful to have a control for variance?
Would it be useful to allow sample values greater than 0 dB?
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46814
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by Robert J. H. » Wed Jan 27, 2016 12:03 pm

steve wrote:In a white noise plug-in, would it be useful to have a control for variance?
Would it be useful to allow sample values greater than 0 dB?


Do you mean a separate (Nyquist) plug-in?
Variance might be OK, but I wouldn't allow samples > +/-1.0.
You should at least set the limit for the RMS at -4.8 dB (as with uniformly distributed white noise), I think.
Robert J. H.
 
Posts: 1813
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 7

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by steve » Wed Jan 27, 2016 12:54 pm

Robert J. H. wrote:Do you mean a separate (Nyquist) plug-in?

I think that heneric was thinking of C++, which would probably be better for speed unless someone writes a fast primitive for Gaussian noise in Nyquist.

Robert J. H. wrote:Variance might be OK, but I wouldn't allow samples > +/-1.0.

For 32-bit float, values greater than 0 dB are valid. For specialist use cases where uniform distribution white noise is not suitable, values greater than 0 dB may be needed, (though I don't recall anyone yet giving pracical use cases where Gaussian rather than uniform white noise is actually required).

Robert J. H. wrote:You should at least set the limit for the RMS at -4.8 dB (as with uniformly distributed white noise), I think.

That begs the question, if you want it to be "like" uniform white noise, why not just stick with uniform white noise?

I'm still intrigued why Audacity's white noise appears to be much more than 15-bit on Windows when the code suggests that it shouldn't be. I like to know what's broken before I start fixing something.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46814
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: VS 2015, x64, and Code Cleanup

Permanent link to this post Posted by steve » Wed Jan 27, 2016 1:14 pm

henric wrote:I mean that someone using a generated waveform might not expect it to have a bunch of missing codes.

I'm sure there are "scientific" cases where it makes a difference, just like the spectral gaps in white light are important for some purposes (eg photography, artist paintings). On the other hand, modern "display lighting" has improved a lot from the old fluorescent tube lighting and is perfectly adequate for most purposes.

I'm a bit surprised/concerned that we are approaching page 3 of this discussion and still don't have a compelling use case for why this is necessary,. I agree that "high quality" white noise would be "nice to have" if it can be accomplished without a significant speed penalty. I also agree that Gaussian white noise could be a useful optional extra for some users, though I'm not aware of any demand prior to this discussion with henric.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46814
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

PreviousNext

Return to Compiling Audacity



Who is online

Users browsing this forum: No registered users and 1 guest