22 May '13 - 08:56 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: BASS_ChannelGetLevel - true level?  (Read 1678 times)
DoctorJellybean
Posts: 3


« on: 1 Jun '10 - 19:50 »
Reply with quoteQuote

Firstly, I like to thank 3delite for introducing me to BASS, and for his help in figuring the code out (Delphi)  Smiley

He created a simple media player to show me how to use a VU Meter.

Quote
procedure TForm1.FormCreate(Sender: TObject);
begin
    //* Never forget to init BASS
    BASS_Init(-1, 41000, 0, Self.Handle, 0);
    //* Set VU max. values
    Gauge1.MaxValue := High(Word);
    Gauge2.MaxValue := High(Word);
end;

It then calls a timer when playing a stream

Quote
procedure TForm1.Timer1Timer(Sender: TObject);
var
    Level: Cardinal;
    LeftLevel: Word;
    RightLevel: Word;
begin
    Level := BASS_ChannelGetLevel(Channel);
    //* Separate L & R channel
    LeftLevel := LoWord(Level);
    RightLevel := HiWord(Level);
    //* Set the VUs
    Gauge1.Progress := LeftLevel;
    Gauge2.Progress := RightLevel;
end;

My question is: does this display the true audio peak levels? 3delite suspects that it does, but suggested that I ask on here.

The reason I'm asking is because the peak levels with the above code and the peak levels when playing the same audio file in Sony SoundForge appears to be different.

This is a screenshot of a peak from the above code


In Sony SoundForge, the peaks at the same point in the audio track are


As you can see, the Sony peaks are almost at the top, hovering between the yellow and red. The BASS peaks are much lower, and never even reach halfway.

If it is not the the true peaks, how do I obtain it?

Thanks in advance.
Logged
Ian @ un4seen
Administrator
Posts: 15259


« Reply #1 on: 2 Jun '10 - 17:00 »
Reply with quoteQuote

    Gauge1.MaxValue := High(Word);
    Gauge2.MaxValue := High(Word);

I'm not a Delphi user, but I guess "High(Word)" gives the maximum unsigned 16-bit value, ie. 65535? The maximum level returned by BASS_ChannelGetLevel is 32768, so that would explain why your display never goes beyond halfway Smiley

Anyway, it looks like the main difference between the 2 displays is that yours is using a linear scale while the other is using a logarithmic (dB) scale. To make yours logarithmic, you could do something like this...

float fLevel;
if (LeftLevel) {
fLevel=1+log10(LeftLevel/32768.0)*20/LevelRange;
if (fLevel<0) fLevel=0; // the level is below the display range
} else
fLevel=0;
Gauge1.Progress = fLevel*DisplayRange;

if (RightLevel) {
fLevel=1+log10(RightLevel/32768.0)*20/LevelRange;
if (fLevel<0) fLevel=0; // the level is below the display range
} else
fLevel=0;
Gauge2.Progress = fLevel*DisplayRange;

Where "LevelRange" is the level range to display (eg. 30 = 0 to -30 dB), and "DisplayRange" is the range of the level display/control (eg. the Gauge1.MaxValue setting).
Logged
ZuBy
Posts: 46


« Reply #2 on: 2 Jun '10 - 19:26 »
Reply with quoteQuote

Hi

set max values
    Gauge1.MaxValue := 100;
    Gauge2.MaxValue := 100;
 

onTimer
    level := BASS_ChannelGetLevel(chan); // scan peaks
    Gauge1.Progress := MulDiv(100, LOWORD(Level), 32768); // set left peak
    Gauge2.Progress := MulDiv(100, HIWORD(Level), 32768); // set right peak

ZuBy
Logged
DoctorJellybean
Posts: 3


« Reply #3 on: 2 Jun '10 - 20:06 »
Reply with quoteQuote

Thank you Ian for the solution, and ZuBy for the Delphi code  Smiley  All is well and working!
Logged
AnthonyM
Posts: 47


« Reply #4 on: 19 Jan '12 - 06:29 »
Reply with quoteQuote

Sorry to post in an old topic but I wanted to ask a question in regards to the code posted.

1. Does ChannelGetLevel ever return a value of above 0dB? If so what value using the code would be 0dB?

2. Does this code keep the value linear or do I need to label the VU meter in a logarithmic scale? If so is there an easy way I can enter in say 5dB into this code to see where it lines up on the meter and label it?



Thanks Smiley
Logged
Ian @ un4seen
Administrator
Posts: 15259


« Reply #5 on: 19 Jan '12 - 16:40 »
Reply with quoteQuote

1. Does ChannelGetLevel ever return a value of above 0dB? If so what value using the code would be 0dB?

No, BASS_ChannelGetLevel limits it to 0dB (32768). It is possible for floating-point channels (using the BASS_SAMPLE_FLOAT flag) to have sample data that goes above 0dB, and if detection of that is required, then BASS_ChannelGetData can be used instead, ie. get the peak level from the sample data yourself.

2. Does this code keep the value linear or do I need to label the VU meter in a logarithmic scale? If so is there an easy way I can enter in say 5dB into this code to see where it lines up on the meter and label it?

Do you mean the code in this thread? If so, Zuby's code does keep it linear, while the code I posted converts to logarithmic. As BASS_ChannelGetLevel limits the level to 0dB, there's no need for 5dB on the meter Smiley
Logged
AnthonyM
Posts: 47


« Reply #6 on: 19 Jan '12 - 21:29 »
Reply with quoteQuote

Sorry that was a typo.

I was referring to your posted code and how I might go about labeling -30, -20, -15, -10, -7, -5, -3, -2, -1 and 0.
Obviously -30 and 0 are easy, but is there some way I can visually see where the others are?
Logged
Ian @ un4seen
Administrator
Posts: 15259


« Reply #7 on: 20 Jan '12 - 16:30 »
Reply with quoteQuote

The dB levels would be arranged linearly on the meter with that code. For example, if 0dB is at the top and -30dB is at the bottom, then -15dB would be in the middle.
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines