SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Classes | Public Member Functions | Public Attributes | Static Private Member Functions | Private Attributes | List of all members
AudioCompressorSnd Class Reference

#include <audiocompressorsnd.h>

+ Collaboration diagram for AudioCompressorSnd:

Classes

struct  CompressorState
 

Public Member Functions

 AudioCompressorSnd ()
 
 ~AudioCompressorSnd ()
 
void initDefault (int rate)
 
void initSimple (int rate, float pregain, float threshold, float knee, float ratio, float attack, float release)
 
void initState ()
 
float compress (float sample)
 

Public Attributes

float m_rate
 
float m_pregain
 
float m_threshold
 
float m_knee
 
float m_ratio
 
float m_attack
 
float m_release
 
float m_predelay
 
float m_releasezone1
 
float m_releasezone2
 
float m_releasezone3
 
float m_releasezone4
 
float m_postgain
 
float m_wet
 

Static Private Member Functions

static float db2lin (float db)
 
static float lin2db (float lin)
 
static float kneecurve (float x, float k, float linearthreshold)
 
static float kneeslope (float x, float k, float linearthreshold)
 
static float compcurve (float x, float k, float slope, float linearthreshold, float linearthresholdknee, float threshold, float knee, float kneedboffset)
 
static float adaptivereleasecurve (float x, float a, float b, float c, float d)
 
static float clampf (float v, float min, float max)
 
static float absf (float v)
 
static float fixf (float v, float def)
 
static void sf_compressor_process (CompressorState *state, int size, float *input, float *output)
 

Private Attributes

CompressorState m_compressorState
 
float m_storageBuffer [AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]
 
float m_processedBuffer [AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]
 
int m_sampleIndex
 

Detailed Description

Definition at line 46 of file audiocompressorsnd.h.

Constructor & Destructor Documentation

◆ AudioCompressorSnd()

AudioCompressorSnd::AudioCompressorSnd ( )

Definition at line 29 of file audiocompressorsnd.cpp.

References AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE, m_processedBuffer, and m_sampleIndex.

30 {
31  m_sampleIndex = 0;
33 }
#define AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE
float m_processedBuffer[AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]

◆ ~AudioCompressorSnd()

AudioCompressorSnd::~AudioCompressorSnd ( )

Definition at line 35 of file audiocompressorsnd.cpp.

36 {}

Member Function Documentation

◆ absf()

static float AudioCompressorSnd::absf ( float  v)
inlinestaticprivate

Definition at line 158 of file audiocompressorsnd.h.

Referenced by sf_compressor_process().

158  {
159  return v < 0.0f ? -v : v;
160  }
+ Here is the caller graph for this function:

◆ adaptivereleasecurve()

static float AudioCompressorSnd::adaptivereleasecurve ( float  x,
float  a,
float  b,
float  c,
float  d 
)
inlinestaticprivate

Definition at line 148 of file audiocompressorsnd.h.

Referenced by sf_compressor_process().

148  {
149  // a*x^3 + b*x^2 + c*x + d
150  float x2 = x * x;
151  return a * x2 * x + b * x2 + c * x + d;
152  }
+ Here is the caller graph for this function:

◆ clampf()

static float AudioCompressorSnd::clampf ( float  v,
float  min,
float  max 
)
inlinestaticprivate

Definition at line 154 of file audiocompressorsnd.h.

References leansdr::max().

Referenced by sf_compressor_process().

154  {
155  return v < min ? min : (v > max ? max : v);
156  }
T max(const T &x, const T &y)
Definition: framework.h:446
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compcurve()

static float AudioCompressorSnd::compcurve ( float  x,
float  k,
float  slope,
float  linearthreshold,
float  linearthresholdknee,
float  threshold,
float  knee,
float  kneedboffset 
)
inlinestaticprivate

Definition at line 135 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd::CompressorState::sf_advancecomp(), and sf_compressor_process().

136  {
137  if (x < linearthreshold)
138  return x;
139  if (knee <= 0.0f) // no knee in curve
140  return db2lin(threshold + slope * (lin2db(x) - threshold));
141  if (x < linearthresholdknee)
142  return kneecurve(x, k, linearthreshold);
143  return db2lin(kneedboffset + slope * (lin2db(x) - threshold - knee));
144  }
static float kneecurve(float x, float k, float linearthreshold)
static float lin2db(float lin)
static float db2lin(float db)
+ Here is the caller graph for this function:

◆ compress()

float AudioCompressorSnd::compress ( float  sample)

Definition at line 58 of file audiocompressorsnd.cpp.

References AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE, m_compressorState, m_processedBuffer, m_sampleIndex, m_storageBuffer, and sf_compressor_process().

Referenced by SSBMod::pullAF().

59 {
60  float compressedSample;
61 
63  {
65  m_sampleIndex = 0;
66  }
67 
68  compressedSample = m_processedBuffer[m_sampleIndex];
70  m_sampleIndex++;
71 
72  return compressedSample;
73 }
#define AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE
CompressorState m_compressorState
float m_storageBuffer[AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]
static void sf_compressor_process(CompressorState *state, int size, float *input, float *output)
float m_processedBuffer[AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ db2lin()

static float AudioCompressorSnd::db2lin ( float  db)
inlinestaticprivate

Definition at line 117 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd::CompressorState::sf_advancecomp(), and sf_compressor_process().

117  { // dB to linear
118  return powf(10.0f, 0.05f * db);
119  }
+ Here is the caller graph for this function:

◆ fixf()

static float AudioCompressorSnd::fixf ( float  v,
float  def 
)
inlinestaticprivate

Definition at line 162 of file audiocompressorsnd.h.

Referenced by sf_compressor_process().

162  {
163  // fix NaN and infinity values that sneak in... not sure why this is needed, but it is
164  if (isnan(v) || isinf(v))
165  return def;
166  return v;
167  }
+ Here is the caller graph for this function:

◆ initDefault()

void AudioCompressorSnd::initDefault ( int  rate)
inline

Definition at line 52 of file audiocompressorsnd.h.

53  {
54  m_rate = rate;
55  m_pregain = 0.000f;
56  m_threshold = -24.000f;
57  m_knee = 30.000f;
58  m_ratio = 12.000f;
59  m_attack = 0.003f;
60  m_release = 0.250f;
61  m_predelay = 0.006f;
62  m_releasezone1 = 0.090f;
63  m_releasezone2 = 0.160f;
64  m_releasezone3 = 0.420f;
65  m_releasezone4 = 0.980f;
66  m_postgain = 0.000f;
67  m_wet = 1.000f;
68  initState();
69  }

◆ initSimple()

void AudioCompressorSnd::initSimple ( int  rate,
float  pregain,
float  threshold,
float  knee,
float  ratio,
float  attack,
float  release 
)
inline

Definition at line 71 of file audiocompressorsnd.h.

Referenced by SSBMod::SSBMod().

80  {
81  m_rate = rate;
82  m_pregain = pregain;
83  m_threshold = threshold;
84  m_knee = knee;
85  m_ratio = ratio;
86  m_attack = attack;
87  m_release = release;
88  m_predelay = 0.006f;
89  m_releasezone1 = 0.090f;
90  m_releasezone2 = 0.160f;
91  m_releasezone3 = 0.420f;
92  m_releasezone4 = 0.980f;
93  m_postgain = 0.000f;
94  m_wet = 1.000f;
95  initState();
96  }
+ Here is the caller graph for this function:

◆ initState()

void AudioCompressorSnd::initState ( )

Definition at line 38 of file audiocompressorsnd.cpp.

References m_attack, m_compressorState, m_knee, m_postgain, m_predelay, m_pregain, m_rate, m_ratio, m_release, m_releasezone1, m_releasezone2, m_releasezone3, m_releasezone4, m_threshold, m_wet, and AudioCompressorSnd::CompressorState::sf_advancecomp().

Referenced by SSBMod::applyAudioSampleRate().

39 {
41  m_rate,
42  m_pregain,
44  m_knee,
45  m_ratio,
46  m_attack,
47  m_release,
48  m_predelay,
53  m_postgain,
54  m_wet
55  );
56 }
CompressorState m_compressorState
void sf_advancecomp(int rate, float pregain, float threshold, float knee, float ratio, float attack, float release, float predelay, float releasezone1, float releasezone2, float releasezone3, float releasezone4, float postgain, float wet)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ kneecurve()

static float AudioCompressorSnd::kneecurve ( float  x,
float  k,
float  linearthreshold 
)
inlinestaticprivate

Definition at line 127 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd::CompressorState::sf_advancecomp().

127  {
128  return linearthreshold + (1.0f - expf(-k * (x - linearthreshold))) / k;
129  }
+ Here is the caller graph for this function:

◆ kneeslope()

static float AudioCompressorSnd::kneeslope ( float  x,
float  k,
float  linearthreshold 
)
inlinestaticprivate

Definition at line 131 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd::CompressorState::sf_advancecomp().

131  {
132  return k * x / ((k * linearthreshold + 1.0f) * expf(k * (x - linearthreshold)) - 1);
133  }
+ Here is the caller graph for this function:

◆ lin2db()

static float AudioCompressorSnd::lin2db ( float  lin)
inlinestaticprivate

Definition at line 121 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd::CompressorState::sf_advancecomp(), and sf_compressor_process().

121  { // linear to dB
122  return 20.0f * log10f(lin);
123  }
+ Here is the caller graph for this function:

◆ sf_compressor_process()

void AudioCompressorSnd::sf_compressor_process ( AudioCompressorSnd::CompressorState state,
int  size,
float *  input,
float *  output 
)
staticprivate

Definition at line 188 of file audiocompressorsnd.cpp.

References AudioCompressorSnd::CompressorState::a, absf(), adaptivereleasecurve(), AudioCompressorSnd::CompressorState::attacksamplesinv, AUDIOCOMPRESSORSND_SF_COMPRESSOR_SPACINGDB, AUDIOCOMPRESSORSND_SF_COMPRESSOR_SPU, AudioCompressorSnd::CompressorState::b, AudioCompressorSnd::CompressorState::c, clampf(), compcurve(), AudioCompressorSnd::CompressorState::compgain, AudioCompressorSnd::CompressorState::d, db2lin(), AudioCompressorSnd::CompressorState::delaybuf, AudioCompressorSnd::CompressorState::delaybufsize, AudioCompressorSnd::CompressorState::delayreadpos, AudioCompressorSnd::CompressorState::delaywritepos, AudioCompressorSnd::CompressorState::detectoravg, AudioCompressorSnd::CompressorState::dry, fixf(), AudioCompressorSnd::CompressorState::k, AudioCompressorSnd::CompressorState::knee, AudioCompressorSnd::CompressorState::kneedboffset, lin2db(), AudioCompressorSnd::CompressorState::linearpregain, AudioCompressorSnd::CompressorState::linearthreshold, AudioCompressorSnd::CompressorState::linearthresholdknee, M_PI, AudioCompressorSnd::CompressorState::mastergain, AudioCompressorSnd::CompressorState::maxcompdiffdb, AudioCompressorSnd::CompressorState::metergain, AudioCompressorSnd::CompressorState::meterrelease, AudioCompressorSnd::CompressorState::satreleasesamplesinv, AudioCompressorSnd::CompressorState::slope, AudioCompressorSnd::CompressorState::threshold, and AudioCompressorSnd::CompressorState::wet.

Referenced by compress().

189 {
190  // pull out the state into local variables
191  float metergain = state->metergain;
192  float meterrelease = state->meterrelease;
193  float threshold = state->threshold;
194  float knee = state->knee;
195  float linearpregain = state->linearpregain;
196  float linearthreshold = state->linearthreshold;
197  float slope = state->slope;
198  float attacksamplesinv = state->attacksamplesinv;
199  float satreleasesamplesinv = state->satreleasesamplesinv;
200  float wet = state->wet;
201  float dry = state->dry;
202  float k = state->k;
203  float kneedboffset = state->kneedboffset;
204  float linearthresholdknee = state->linearthresholdknee;
205  float mastergain = state->mastergain;
206  float a = state->a;
207  float b = state->b;
208  float c = state->c;
209  float d = state->d;
210  float detectoravg = state->detectoravg;
211  float compgain = state->compgain;
212  float maxcompdiffdb = state->maxcompdiffdb;
213  int delaybufsize = state->delaybufsize;
214  int delaywritepos = state->delaywritepos;
215  int delayreadpos = state->delayreadpos;
216  float *delaybuf = state->delaybuf;
217 
218  int samplesperchunk = AUDIOCOMPRESSORSND_SF_COMPRESSOR_SPU;
219  int chunks = size / samplesperchunk;
220  float ang90 = (float)M_PI * 0.5f;
221  float ang90inv = 2.0f / (float)M_PI;
222  int samplepos = 0;
224 
225  for (int ch = 0; ch < chunks; ch++)
226  {
227  detectoravg = fixf(detectoravg, 1.0f);
228  float desiredgain = detectoravg;
229  float scaleddesiredgain = asinf(desiredgain) * ang90inv;
230  float compdiffdb = lin2db(compgain / scaleddesiredgain);
231 
232  // calculate envelope rate based on whether we're attacking or releasing
233  float enveloperate;
234  if (compdiffdb < 0.0f)
235  { // compgain < scaleddesiredgain, so we're releasing
236  compdiffdb = fixf(compdiffdb, -1.0f);
237  maxcompdiffdb = -1; // reset for a future attack mode
238  // apply the adaptive release curve
239  // scale compdiffdb between 0-3
240  float x = (clampf(compdiffdb, -12.0f, 0.0f) + 12.0f) * 0.25f;
241  float releasesamples = adaptivereleasecurve(x, a, b, c, d);
242  enveloperate = db2lin(spacingdb / releasesamples);
243  }
244  else
245  { // compresorgain > scaleddesiredgain, so we're attacking
246  compdiffdb = fixf(compdiffdb, 1.0f);
247  if (maxcompdiffdb == -1 || maxcompdiffdb < compdiffdb)
248  maxcompdiffdb = compdiffdb;
249  float attenuate = maxcompdiffdb;
250  if (attenuate < 0.5f)
251  attenuate = 0.5f;
252  enveloperate = 1.0f - powf(0.25f / attenuate, attacksamplesinv);
253  }
254 
255  // process the chunk
256  for (int chi = 0; chi < samplesperchunk; chi++, samplepos++,
257  delayreadpos = (delayreadpos + 1) % delaybufsize,
258  delaywritepos = (delaywritepos + 1) % delaybufsize)
259  {
260 
261  float inputL = input[samplepos] * linearpregain;
262  delaybuf[delaywritepos] = inputL;
263 
264  inputL = absf(inputL);
265  float inputmax = inputL;
266 
267  float attenuation;
268  if (inputmax < 0.0001f)
269  attenuation = 1.0f;
270  else
271  {
272  float inputcomp = compcurve(inputmax, k, slope, linearthreshold,
273  linearthresholdknee, threshold, knee, kneedboffset);
274  attenuation = inputcomp / inputmax;
275  }
276 
277  float rate;
278  if (attenuation > detectoravg)
279  { // if releasing
280  float attenuationdb = -lin2db(attenuation);
281  if (attenuationdb < 2.0f)
282  attenuationdb = 2.0f;
283  float dbpersample = attenuationdb * satreleasesamplesinv;
284  rate = db2lin(dbpersample) - 1.0f;
285  }
286  else
287  rate = 1.0f;
288 
289  detectoravg += (attenuation - detectoravg) * rate;
290  if (detectoravg > 1.0f)
291  detectoravg = 1.0f;
292  detectoravg = fixf(detectoravg, 1.0f);
293 
294  if (enveloperate < 1) // attack, reduce gain
295  compgain += (scaleddesiredgain - compgain) * enveloperate;
296  else
297  { // release, increase gain
298  compgain *= enveloperate;
299  if (compgain > 1.0f)
300  compgain = 1.0f;
301  }
302 
303  // the final gain value!
304  float premixgain = sinf(ang90 * compgain);
305  float gain = dry + wet * mastergain * premixgain;
306 
307  // calculate metering (not used in core algo, but used to output a meter if desired)
308  float premixgaindb = lin2db(premixgain);
309  if (premixgaindb < metergain)
310  metergain = premixgaindb; // spike immediately
311  else
312  metergain += (premixgaindb - metergain) * meterrelease; // fall slowly
313 
314  // apply the gain
315  output[samplepos] = delaybuf[delayreadpos] * gain;
316  }
317  }
318 
319  state->metergain = metergain;
320  state->detectoravg = detectoravg;
321  state->compgain = compgain;
322  state->maxcompdiffdb = maxcompdiffdb;
323  state->delaywritepos = delaywritepos;
324  state->delayreadpos = delayreadpos;
325 }
#define AUDIOCOMPRESSORSND_SF_COMPRESSOR_SPACINGDB
static float absf(float v)
static float fixf(float v, float def)
static float adaptivereleasecurve(float x, float a, float b, float c, float d)
#define M_PI
Definition: rdsdemod.cpp:27
static float compcurve(float x, float k, float slope, float linearthreshold, float linearthresholdknee, float threshold, float knee, float kneedboffset)
static float lin2db(float lin)
float delaybuf[AUDIOCOMPRESSORSND_SF_COMPRESSOR_MAXDELAY]
static float clampf(float v, float min, float max)
static float db2lin(float db)
#define AUDIOCOMPRESSORSND_SF_COMPRESSOR_SPU
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ m_attack

float AudioCompressorSnd::m_attack

Definition at line 106 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_compressorState

CompressorState AudioCompressorSnd::m_compressorState
private

Definition at line 221 of file audiocompressorsnd.h.

Referenced by compress(), and initState().

◆ m_knee

float AudioCompressorSnd::m_knee

Definition at line 104 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_postgain

float AudioCompressorSnd::m_postgain

Definition at line 113 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_predelay

float AudioCompressorSnd::m_predelay

Definition at line 108 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_pregain

float AudioCompressorSnd::m_pregain

Definition at line 102 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_processedBuffer

float AudioCompressorSnd::m_processedBuffer[AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]
private

Definition at line 223 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd(), and compress().

◆ m_rate

float AudioCompressorSnd::m_rate

Definition at line 101 of file audiocompressorsnd.h.

Referenced by SSBMod::applyAudioSampleRate(), and initState().

◆ m_ratio

float AudioCompressorSnd::m_ratio

Definition at line 105 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_release

float AudioCompressorSnd::m_release

Definition at line 107 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_releasezone1

float AudioCompressorSnd::m_releasezone1

Definition at line 109 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_releasezone2

float AudioCompressorSnd::m_releasezone2

Definition at line 110 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_releasezone3

float AudioCompressorSnd::m_releasezone3

Definition at line 111 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_releasezone4

float AudioCompressorSnd::m_releasezone4

Definition at line 112 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_sampleIndex

int AudioCompressorSnd::m_sampleIndex
private

Definition at line 224 of file audiocompressorsnd.h.

Referenced by AudioCompressorSnd(), and compress().

◆ m_storageBuffer

float AudioCompressorSnd::m_storageBuffer[AUDIOCOMPRESSORSND_SF_COMPRESSOR_CHUNKSIZE]
private

Definition at line 222 of file audiocompressorsnd.h.

Referenced by compress().

◆ m_threshold

float AudioCompressorSnd::m_threshold

Definition at line 103 of file audiocompressorsnd.h.

Referenced by initState().

◆ m_wet

float AudioCompressorSnd::m_wet

Definition at line 114 of file audiocompressorsnd.h.

Referenced by initState().


The documentation for this class was generated from the following files: