Am I doing the right thing to convert decibel from -120 - 0 to 0 - 120

后端 未结 5 1708
忘了有多久
忘了有多久 2020-12-23 23:47

I will like to measure the sound volume of the surrounding, not too sure if I am doing the right thing.

I will like to create a VU meter of a range of 0(quiet) to 12

相关标签:
5条回答
  • 2020-12-24 00:23

    Actually, the range of decibels is from -160 to 0, but it can go to positive values.(AVAudioRecorder Class Reference - averagePowerForChannel: method)

    Then is better write db += 160; instead of db += 120;. Of course you can also put an offset to correct it.

    0 讨论(0)
  • 2020-12-24 00:25

    I make a regression model to convert the mapping relation between the wav data generated from NSRecorder and the decibel data from NSRecorder.averagePowerForChannel

    NSRecorder.averagePowerForChannel (dB) = -80+6 log2(wav_RMS)

    Where wav_RMS is root mean square value of wav data in a short time, i.e. 0.1 sec.

    0 讨论(0)
  • 2020-12-24 00:26

    The formula for converting a linear amplitude to decibels when you want to use 1.0 as your reference (for 0db), is

    20 * log10(amp);
    

    So I'm not sure about the intent from looking at your code, but you probably want

    float db = 20 * log10([recorder averagePowerForChannel:0]);
    

    This will go from -infinity at an amplitude of zero, to 0db at an amplitude of 1. If you really need it to go up to between 0 and 120 you can add 120 and use a max function at zero.

    So, after the above line:

    db += 120;
    db = db < 0 ? 0 : db;
    

    The formula you are using appears to be the formula for converting DB to amp, which I think is the opposite of what you want.

    Edit: I reread and it seems you may already have the decibel value.

    If this is the case, just don't convert to amplitude and add 120.

    So Change

    double peakPowerForChannel = pow(10, (0.05 * [recorder averagePowerForChannel:0]));
    

    to

    double peakPowerForChannel = [recorder averagePowerForChannel:0];
    

    and you should be okay to go.

    0 讨论(0)
  • 2020-12-24 00:32

    Apple uses a lookup table in their SpeakHere sample that converts from dB to a linear value displayed on a level meter. This is to save device power (I guess).

    I also needed this, but didn't think a couple of float calculations every 1/10s (my refresh rate) would cost so much device power. So, instead of building up a table I moulded their code into:

    float       level;                // The linear 0.0 .. 1.0 value we need.
    const float minDecibels = -80.0f; // Or use -60dB, which I measured in a silent room.
    float       decibels    = [audioRecorder averagePowerForChannel:0];
    
    if (decibels < minDecibels)
    {
        level = 0.0f;
    }
    else if (decibels >= 0.0f)
    {
        level = 1.0f;
    }
    else
    {
        float   root            = 2.0f;
        float   minAmp          = powf(10.0f, 0.05f * minDecibels);
        float   inverseAmpRange = 1.0f / (1.0f - minAmp);
        float   amp             = powf(10.0f, 0.05f * decibels);
        float   adjAmp          = (amp - minAmp) * inverseAmpRange;
    
        level = powf(adjAmp, 1.0f / root);
    }
    

    I'm using an AVAudioRecorder, hence you see getting the dB's with averagePowerForChannel:, but you can fill your own dB value there.

    Apple's example used double calculations, which I don't understand because for audio metering float accuracy is more than sufficient, and costs less device power.

    Needless to say, you can now scale this calculated level to your 0 .. 120 range with a simple level * 120.0f.

    The above code can be sped up when we fix root at 2.0f, by replacing powf(adjAmp, 1.0f / root) with sqrtf(adjAmp); but that's a minor thing, and a very good compiler might be able to do this for us. And I'm almost sure that inverseAmpRange will be calculated once at compile-time.

    0 讨论(0)
  • 2020-12-24 00:36

    Simply set your maximum and minimum value. Like you getting range of 0-120. If you want range of 0-60. Simply divide value to half to get the half range and so on..

    0 讨论(0)
提交回复
热议问题