Help with math

Hope I do i better this time. Last time I apparently violated MBS license policy.
Anyways I’m trying to create a simple audio recorder with gauges as input meters.
The idea is that i a have a blue cirkle on the background and an orange arc shape which alters depending on the input on top of the blue cirkle. And finally at the top a cirkle in the middle of the two covering the center so it looks like a donut – if you like.
What I have now works perfectly, but i want -9dB to be at 9 o’clock. Now it is at 4 o’clock. And I can’t figuren that part out.

What I have

in a timer:

if Self.recorder <> NIL Then
          DecibelsL = recorder.peakPowerForChannel(0)
          DecibelsR = recorder.peakPowerForChannel(1)
          If DecibelsL > 0.0 Then
            DecibelsL = 0.0
          End if
          If DecibelsR > 0.0 Then
            DecibelsR = 0.0
          End if
          pValueL = (pow(10.0, 0.05 * DecibelsL) * 360.0)
          pValueR = (pow(10.0, 0.05 * DecibelsR) * 360.0)
          Self.ArcAngleL = (1.57 * 4.0) * (pValueL / 360.0)
          Self.ArcAngleR = (1.57 * 4.0) * (pValueR / 360.0)
        End if

And in the paint event of a canvas where the cirkles and the arc liv:

/Bg Circles
        g.ForeColor = &c012F8C
        g.FillOval(0, 0, 160, 160)
        g.FillOval(200, 0, 160, 160)

        //Decibel Circles
        'Var aL As New ArcShape
        'Var aR As New ArcShape
        Me.aL.Width = 160
        Me.aR.Width = 160
        Me.aL.Height = 160
        Me.aR.Height = 160
        Me.aL.ArcAngle = Self.ArcAngleL
        Me.aR.ArcAngle = Self.ArcAngleR
        Me.aL.StartAngle = -1.57
        Me.aR.StartAngle = -1.57
        If DecibelsL > -9 Then
          Me.aL.FillColor = &cFF0000
          Me.aL.FillColor = &cff5500
        End if
        If DecibelsR> -9 Then
          Me.aR.FillColor = &cFF0000
          Me.aR.FillColor = &cff5500
        End if
        g.DrawObject(Me.aL, 80, 80)
        g.DrawObject(Me.aR, 280, 80)

        //Cover Circles
        If color.IsDarkMode Then
          g.ForeColor = &c262626
          g.ForeColor = &cECECEC
        End If
        g.FillOval(18, 18, 124, 124)
        g.FillOval(218, 18, 124, 124)

        If recorder <> NIL then
          If color.IsDarkMode Then
            g.ForeColor = &cFFFFFF
            g.ForeColor = &c000000
          End If
          g.DrawText(DecibelsL.ToString, 54, 54)
        End if

In a run nethod of the window:

dim f as FolderItem = SpecialFolder.Desktop.Child("test.m4a")

dim recordSetting as new Dictionary

dim n as integer = OSTypeFromStringMBS(AVFoundation.kAudioFormatAppleLossless)
recordSetting.Value(AVFoundationMBS.AVFormatIDKey) = n
recordSetting.Value(AVFoundationMBS.AVSampleRateKey) = 48000.0
recordSetting.Value(AVFoundationMBS.AVNumberOfChannelsKey) = 2
recordSetting.Value(AVFoundationMBS.AVLinearPCMBitDepthKey) = 24
recordSetting.Value(AVFoundationMBS.AVLinearPCMIsBigEndianKey) = false
recordSetting.Value(AVFoundationMBS.AVLinearPCMIsFloatKey) = false

dim error as NSErrorMBS
recorder = new AVAudioRecorderMBS(f, recordSetting, error)
recorder.MeteringEnabled = True
if error<>Nil then
  MsgBox error.LocalizedDescription
end if

if recorder.record then
  // ok
  AVFoundation.CurrentFile = f
  MsgBox "Failed to start recording."
end if

Im using AVFoundation from MBS and you can check out the project if you have the MBS plugins. You don’t need a licence if you run it from the XOJO IDE

Hope I dit it right this time :sweat:

you can find my project here:

Why are you doing this?

What value do you want to get at 12 o’clock (for the lowest power)? And for the max power?


To be honest. I don’t know :face_with_hand_over_mouth: it was something I found and it kind of worked.
At 12 o’clock I want -160dB and 0dB. Please note that dB’s are logaritmic.

That’s why I asked about that specific code line, you are undoing the logartithmic scale with that power operation.

Your decibels go from -160 to 0 (and -9 is a relevant value for you) and after you apply that power conversion the values go from 10^-8 to 1 (where the new value correponding to -9dB is 0.3548).

None of those two scales (the initial logarthmic one and the one you obtain after you apply your power conversion) will adjust properly to what you want to achieve with a linear conversion like

You need to define a non-linear transformation for your Decibels or pValue that will return the values you want (0 for -160dB, 270 for -9dB and 360 for 0 dB). Using those three points I found the following expression does a pretty good job at getting the output you need (converting directly Decibels to ArcAngle):

ArcAngle = 3.82202e-9*(Decibels+161.6)^4.96912

Give it a try.


1 Like

Thanks a lot Julen_I

I certainly will when time allows.

I wil let you know how it all goes :slight_smile:

Hi Julen
I tried you solution but the meter flickers to much (rapidly go from one value to another) Maybe I do it wrong :face_with_hand_over_mouth:

Have you checked the Decibels? Do they change rapidly too?

Your three reference values (-160dB, 0º ; -9dB, 270º; 0bB, 360º) can be fitted using different kinds of expressions. The type of expression used will affect the output.

If you plot those three points and the expression I used you will see that it fits your data welll. Also, you will see that it has an almost completely flat and long tail to the left (below -100/-80 dB) and then the value incresases quickly (steep slope), which means that a variation of a few decibels may result in a large variation in the output. For example, a chage of 10 dB (from -30 to -20) will result in a variation of 60 º in the angle, which seems a lot, indeed:


I just fitted your data with an expression that in my opinion had a correct shape (and provided a good fit). If that shape isn’t what you need you will have to define in more detail what you want. For example which angle values you would like to have for several different decibel values (power values).


Yes the decibels change rapidly to. My recorder is for voice recording and the reason -9dB is interesting is that this is our max level for broadcast.
So I want to show the max level immediately and then let the gauge “relax” slowly. I think what you did is totally right but I haven’t explained my self good enough.

I’ve created a small video of what I want to achieve:
What I have now works but it’s based on my guessing/trial and error. I would like to do it the right way.

If you want me to try to find an expression that mimics what you are showing in that video I need data (decibel-angle pairs) for the entire range of values. I think getting them every 10-20 decibels would be more than enough.


1 Like

Thats a very kind offer, thank you. But I don’t know how to provide the data.
I don’t how to go beyond XOJO or even to the borders of XOJO and relay on the MBS plugin. The decibels comes from the AVAudioRecorderMBS

Thanx again

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.