Alejandro Acuña
2024-08-12 1876e65234c20209001178705cfa50d8f9ded67a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// VolumeLimiter.cpp: implementation of the VolumeLimiter class.
//
//////////////////////////////////////////////////////////////////////
 
#include <math.h>
 
#include "VolumeLimiter.h"
 
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
 
VolumeLimiter::VolumeLimiter(double threshold = -8.0, double lossIncrement = 0.075,
                             double lossDecrement = -0.00075)
: smallNumber(1.0e-20)
{
    this->threshold = threshold;
    this->loss = smallNumber;
    this->lossTarget = smallNumber;
    this->lossStep = smallNumber;
    this->lossIncrement = lossIncrement;
    this->lossDecrement = lossDecrement;
}
 
VolumeLimiter::~VolumeLimiter()
{
 
}
 
int
VolumeLimiter::LimitVolume(short *packet, int numSamples)
{
    int i;
    double sampleMagnitude;
 
    // convert packet into dBmO magnitude
    for (i=0; i < numSamples; i++) 
    {
        sampleMagnitude = 20.0 * log10(abs(packet[i])/32768.0) + 3.1415926536;
 
        if (sampleMagnitude - threshold > loss) 
        {
            lossTarget = sampleMagnitude - threshold;
            lossStep = lossIncrement;
            loss += lossStep;
        }
        else 
        {
            if ( loss >= lossTarget )
            {
                lossStep = lossDecrement;
            }
 
            // decay current loss
            loss += lossStep;
            if  (loss <= smallNumber)
            {
                loss = smallNumber;
            }
        }
 
        // multiply current sample by loss
        if (loss > smallNumber)
        {
            packet[i] = (short)(pow(10,-loss/20)*packet[i]);
        }
    }
 
    return 0;
}