Author Topic: Generate White Noise  (Read 479 times)

David_AVD

  • Posts: 80
Generate White Noise
« on: 19 Oct '23 - 22:08 »
Is there any function in Bass to generate white noise ?

If not, is it possible to do programmatically ?

Ian @ un4seen

  • Administrator
  • Posts: 25613
Re: Generate White Noise
« Reply #1 on: 20 Oct '23 - 12:00 »
White noise is just totally random numbers. So you could do something like this:

Code: [Select]
BASS_INFO info;
BASS_GetInfo(&info);
noise = BASS_StreamCreate(info.freq, 1, 0, NoiseStreamProc, 0);

...

DWORD CALLBACK NoiseStreamProc(HSTREAM handle, void *buffer, DWORD length, void *user)
{
short *dest = (short*)buffer;
for (DWORD a = 0; a < length / sizeof(short); a++)
dest[a] = (short)(rand() << 1); // shift up 1 bit because rand returns 15-bit values
return length;
}

Note the output device's rate (info.freq) is used to avoid resampling/filtering (which would stop it being pure white noise).

David_AVD

  • Posts: 80
Re: Generate White Noise
« Reply #2 on: 20 Oct '23 - 22:38 »
Thanks for the reply. I'll give that a go.

David_AVD

  • Posts: 80
Re: Generate White Noise
« Reply #3 on: 22 Oct '23 - 03:00 »
Can anyone help with converting the NoiseStreamProc code above to Delphi ?

Chris

  • Posts: 2185
Re: Generate White Noise
« Reply #4 on: 22 Oct '23 - 11:26 »
Hi

Code: [Select]
var  Noise: Hstream;

function NoiseStreamProc(Fstream: Hstream; buffer: Pointer; length: DWORD; user: Pointer): DWORD; stdcall;
type
  TDestArray = array [0 .. (maxInt div sizeof(ShortInt)) - 1] of ShortInt;
  PDestArray = ^TDestArray;
var
  fdest: PDestArray;
  a: integer;
begin
  fdest := Pointer(buffer);
  for a := 0 to (length div sizeof(ShortInt)) - 1 do
    fdest[a] := ShortInt(Random(High(ShortInt)));
  Result := length;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Info: BASS_INFO;
begin
  randomize;
  BASS_GetInfo(Info);
  Bass_Init(-1, 44100, 0, handle, nil);
  Noise := BASS_StreamCreate(Info.freq, 1, 0, NoiseStreamProc, nil);
end;
« Last Edit: 22 Oct '23 - 12:28 by Chris »

David_AVD

  • Posts: 80
Re: Generate White Noise
« Reply #5 on: 22 Oct '23 - 21:50 »
Thank you so much guys. I had most of the translation done, but was trying to work out the buffer syntax.

I can confirm that it works. :)

Could pink noise be done the same way with an FX filter applied to the white noise stream?

Ian @ un4seen

  • Administrator
  • Posts: 25613
Re: Generate White Noise
« Reply #6 on: 23 Oct '23 - 16:37 »
Code: [Select]
    fdest[a] := ShortInt(Random(High(ShortInt)));

If I understand correctly, that line will generate sample values between 0-32766. 16-bit sample data is signed, so the generated data should ideally contain both positive and negative values (with an average of ~0). I think this would do it:

Code: [Select]
    fdest[a] := ShortInt(Random(65536) - 32768);

Depending on how Delphi handles the Integer/ShortInt type-casting, the -32768 part may not be necessary. For example, it isn't needed in the C/C++ case above.

Could pink noise be done the same way with an FX filter applied to the white noise stream?

Pink noise is more complicated to generate. I don't think you'll be able to do it with BASS_FX filters, but Googling will reveal several different methods for it. The "Paul Kellet's economy method" shown here is probably the simplest:

   https://www.firstpr.com.au/dsp/pink-noise/

David_AVD

  • Posts: 80
Re: Generate White Noise
« Reply #7 on: 23 Oct '23 - 21:53 »
This does produce positive and negative numbers:
Code: [Select]
fdest[a] := ShortInt(Random(65536));
I was hoping that there was a simple way to apply the 3dB per octave filter in Bass.

The info in the link provided is probably beyond my math / coding capabilities.

I'm still happy with the white noise generation though. Thank you. :)

Chris

  • Posts: 2185
Re: Generate White Noise
« Reply #8 on: 24 Oct '23 - 20:00 »
oops that was a error from me
by the way the translation c-> Delphi was not correct from me.  C++ (short/int16, –32.768 .. 32.767, 16Bit) have complete other Values as a Delphi ShortInt() (-128..127, 8Bit)
so it must be in Delphi a SmallInt (–32.768 .. 32.767, 16Bit)
so the correction should to be

Code: [Select]
function NoiseStreamProc(Fstream: Hstream; buffer: Pointer; length: DWORD; user: Pointer): DWORD; stdcall;
type
  TDestArray = array [0 .. (maxInt div sizeof(SmallInt)) - 1] of SmallInt;
  PDestArray = ^TDestArray;
var
  fdest: PDestArray;
  a: integer;
begin
  fdest := Pointer(buffer);
  for a := 0 to (length div sizeof(SmallInt)) - 1 do
  begin
    fdest[a] := SmallInt(Random(65535));
  end;
  Result := length;
end;

« Last Edit: 24 Oct '23 - 20:08 by Chris »

David_AVD

  • Posts: 80
Re: Generate White Noise
« Reply #9 on: 24 Oct '23 - 21:46 »
Thanks Chris.