Audacity 3.2.0
Classes | Typedefs | Functions | Variables
Dither.cpp File Reference
#include "Dither.h"
#include "Internat.h"
#include "Prefs.h"
#include "float_cast.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <wx/defs.h>
Include dependency graph for Dither.cpp:

Go to the source code of this file.

Classes

struct  State
 

Typedefs

using Ditherer = float(*)(State &, float)
 

Functions

static float DITHER_NOISE ()
 
static float FROM_INT16 (const short *ptr)
 
static float FROM_INT24 (const int *ptr)
 
static float FROM_FLOAT (const float *ptr)
 
template<typename dst_type >
static void IMPLEMENT_STORE (dst_type *ptr, float sample, dst_type min_bound, dst_type max_bound)
 
static void DITHER_TO_INT16 (Ditherer dither, State &state, short *dst, float sample)
 
static void DITHER_TO_INT24 (Ditherer dither, State &state, int *dst, float sample)
 
template<typename srcType , typename dstType >
static void DITHER_LOOP (Ditherer dither, State &state, void(*store)(Ditherer, State &, dstType *, float), float(*load)(const srcType *), samplePtr dst, sampleFormat dstFormat, size_t dstStride, constSamplePtr src, sampleFormat srcFormat, size_t srcStride, size_t len)
 
static void DITHER (Ditherer dither, State &state, samplePtr dst, sampleFormat dstFormat, size_t dstStride, constSamplePtr src, sampleFormat srcFormat, size_t srcStride, size_t len)
 
static float NoDither (State &, float sample)
 
static float RectangleDither (State &, float sample)
 
static float TriangleDither (State &state, float sample)
 
static float ShapedDither (State &state, float sample)
 

Variables

constexpr int BUF_SIZE = 8
 
constexpr int BUF_MASK = 7
 
const float SHAPED_BS [] = { 2.033f, -2.165f, 1.959f, -1.590f, 0.6149f }
 
struct State mState
 
constexpr auto CONVERT_DIV16 = float(1<<15)
 
constexpr auto CONVERT_DIV24 = float(1<<23)
 
static const std::initializer_list< EnumValueSymbolchoicesDither
 
static auto intChoicesDither
 

Typedef Documentation

◆ Ditherer

using Ditherer = float (*)(State &, float)

Definition at line 73 of file Dither.cpp.

Function Documentation

◆ DITHER()

static void DITHER ( Ditherer  dither,
State state,
samplePtr  dst,
sampleFormat  dstFormat,
size_t  dstStride,
constSamplePtr  src,
sampleFormat  srcFormat,
size_t  srcStride,
size_t  len 
)
inlinestatic

Definition at line 162 of file Dither.cpp.

165{
166 if (srcFormat == int24Sample && dstFormat == int16Sample)
167 DITHER_LOOP<int, short>(dither, state,
169 int16Sample, dstStride, src, int24Sample, srcStride, len);
170 else if (srcFormat == floatSample && dstFormat == int16Sample)
171 DITHER_LOOP<float, short>(dither, state,
173 int16Sample, dstStride, src, floatSample, srcStride, len);
174 else if (srcFormat == floatSample && dstFormat == int24Sample)
175 DITHER_LOOP<float, int>(dither, state,
177 int24Sample, dstStride, src, floatSample, srcStride, len);
178 else { wxASSERT(false); }
179}
static void DITHER_TO_INT24(Ditherer dither, State &state, int *dst, float sample)
Definition: Dither.cpp:132
static float FROM_INT24(const int *ptr)
Definition: Dither.cpp:91
static void DITHER_TO_INT16(Ditherer dither, State &state, short *dst, float sample)
Definition: Dither.cpp:123
static float FROM_FLOAT(const float *ptr)
Definition: Dither.cpp:99
constexpr sampleFormat int16Sample
Definition: SampleFormat.h:43
constexpr sampleFormat floatSample
Definition: SampleFormat.h:45
constexpr sampleFormat int24Sample
Definition: SampleFormat.h:44

References DITHER_TO_INT16(), DITHER_TO_INT24(), floatSample, FROM_FLOAT(), FROM_INT24(), int16Sample, and int24Sample.

Referenced by Dither::Apply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DITHER_LOOP()

template<typename srcType , typename dstType >
static void DITHER_LOOP ( Ditherer  dither,
State state,
void(*)(Ditherer, State &, dstType *, float)  store,
float(*)(const srcType *)  load,
samplePtr  dst,
sampleFormat  dstFormat,
size_t  dstStride,
constSamplePtr  src,
sampleFormat  srcFormat,
size_t  srcStride,
size_t  len 
)
inlinestatic

Definition at line 143 of file Dither.cpp.

148{
149 char *d;
150 const char *s;
151 unsigned int ii;
152 for (d = (char*)dst, s = (char*)src, ii = 0;
153 ii < len;
154 ii++, d += SAMPLE_SIZE(dstFormat) * dstStride,
155 s += SAMPLE_SIZE(srcFormat) * srcStride) {
156 store(dither, state, reinterpret_cast<dstType *>(d), load(reinterpret_cast<const srcType *>(s)));
157 }
158}
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:52

References SAMPLE_SIZE.

◆ DITHER_NOISE()

static float DITHER_NOISE ( )
inlinestatic

Definition at line 76 of file Dither.cpp.

77{
78 return rand() / (float)RAND_MAX - 0.5f;
79}

Referenced by RectangleDither(), ShapedDither(), and TriangleDither().

Here is the caller graph for this function:

◆ DITHER_TO_INT16()

static void DITHER_TO_INT16 ( Ditherer  dither,
State state,
short *  dst,
float  sample 
)
inlinestatic

Definition at line 123 of file Dither.cpp.

125{
126 IMPLEMENT_STORE<short>(dst,
127 dither(state, sample * CONVERT_DIV16),
128 short(-32768), short(32767));
129}
constexpr auto CONVERT_DIV16
Definition: Dither.cpp:82

References CONVERT_DIV16.

Referenced by DITHER().

Here is the caller graph for this function:

◆ DITHER_TO_INT24()

static void DITHER_TO_INT24 ( Ditherer  dither,
State state,
int *  dst,
float  sample 
)
inlinestatic

Definition at line 132 of file Dither.cpp.

134{
135 IMPLEMENT_STORE<int>(dst,
136 dither(state, sample * CONVERT_DIV24), -8388608, 8388607);
137}
constexpr auto CONVERT_DIV24
Definition: Dither.cpp:83

References CONVERT_DIV24.

Referenced by DITHER().

Here is the caller graph for this function:

◆ FROM_FLOAT()

static float FROM_FLOAT ( const float *  ptr)
inlinestatic

Definition at line 99 of file Dither.cpp.

100{
101 return *((float*)(ptr)) > 1.0
102 ? 1.0 :
103 *((float*)(ptr)) < -1.0
104 ? -1.0 :
105 *((float*)(ptr));
106}

Referenced by DITHER().

Here is the caller graph for this function:

◆ FROM_INT16()

static float FROM_INT16 ( const short *  ptr)
inlinestatic

Definition at line 86 of file Dither.cpp.

87{
88 return *ptr / CONVERT_DIV16;
89}

References CONVERT_DIV16.

Referenced by Dither::Apply().

Here is the caller graph for this function:

◆ FROM_INT24()

static float FROM_INT24 ( const int *  ptr)
inlinestatic

Definition at line 91 of file Dither.cpp.

92{
93 return *ptr / CONVERT_DIV24;
94}

References CONVERT_DIV24.

Referenced by Dither::Apply(), and DITHER().

Here is the caller graph for this function:

◆ IMPLEMENT_STORE()

template<typename dst_type >
static void IMPLEMENT_STORE ( dst_type *  ptr,
float  sample,
dst_type  min_bound,
dst_type  max_bound 
)
inlinestatic

Definition at line 110 of file Dither.cpp.

112{
113 int x = lrintf(sample);
114 if (x > max_bound)
115 *ptr = max_bound;
116 else if (x<(min_bound))
117 *ptr = min_bound;
118 else
119 *ptr = static_cast<dst_type>(x);
120}
#define lrintf(flt)
Definition: float_cast.h:170

References lrintf.

◆ NoDither()

float NoDither ( State ,
float  sample 
)
inlinestatic

Definition at line 331 of file Dither.cpp.

332{
333 return sample;
334}

Referenced by Dither::Apply().

Here is the caller graph for this function:

◆ RectangleDither()

float RectangleDither ( State ,
float  sample 
)
inlinestatic

Definition at line 337 of file Dither.cpp.

338{
339 return sample - DITHER_NOISE();
340}
static float DITHER_NOISE()
Definition: Dither.cpp:76

References DITHER_NOISE().

Referenced by Dither::Apply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShapedDither()

float ShapedDither ( State state,
float  sample 
)
inlinestatic

Definition at line 353 of file Dither.cpp.

354{
355 // Generate triangular dither, +-1 LSB, flat psd
356 float r = DITHER_NOISE() + DITHER_NOISE();
357 if(sample != sample) // test for NaN
358 sample = 0; // and do the best we can with it
359
360 // Run FIR
361 float xe = sample + state.mBuffer[state.mPhase] * SHAPED_BS[0]
362 + state.mBuffer[(state.mPhase - 1) & BUF_MASK] * SHAPED_BS[1]
363 + state.mBuffer[(state.mPhase - 2) & BUF_MASK] * SHAPED_BS[2]
364 + state.mBuffer[(state.mPhase - 3) & BUF_MASK] * SHAPED_BS[3]
365 + state.mBuffer[(state.mPhase - 4) & BUF_MASK] * SHAPED_BS[4];
366
367 // Accumulate FIR and triangular noise
368 float result = xe + r;
369
370 // Roll buffer and store last error
371 state.mPhase = (state.mPhase + 1) & BUF_MASK;
372 state.mBuffer[state.mPhase] = xe - lrintf(result);
373
374 return result;
375}
const float SHAPED_BS[]
Definition: Dither.cpp:64
constexpr int BUF_MASK
Definition: Dither.cpp:61
int mPhase
Definition: Dither.cpp:68
float mBuffer[8]
Definition: Dither.cpp:70

References BUF_MASK, DITHER_NOISE(), lrintf, State::mBuffer, State::mPhase, and SHAPED_BS.

Referenced by Dither::Apply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TriangleDither()

float TriangleDither ( State state,
float  sample 
)
inlinestatic

Definition at line 343 of file Dither.cpp.

344{
345 float r = DITHER_NOISE();
346 float result = sample + r - state.mTriangleState;
347 state.mTriangleState = r;
348
349 return result;
350}
float mTriangleState
Definition: Dither.cpp:69

References DITHER_NOISE(), and State::mTriangleState.

Referenced by Dither::Apply().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ BUF_MASK

constexpr int BUF_MASK = 7
constexpr

Definition at line 61 of file Dither.cpp.

Referenced by ShapedDither().

◆ BUF_SIZE

constexpr int BUF_SIZE = 8
constexpr

Definition at line 60 of file Dither.cpp.

Referenced by Dither::Reset().

◆ choicesDither

const std::initializer_list<EnumValueSymbol> choicesDither
static
Initial value:
{
{ XO("None") },
{ XO("Rectangle") },
{ XC("Triangle", "dither") },
{ XO("Shaped") },
}
XO("Cut/Copy/Paste")
#define XC(s, c)
Definition: Internat.h:37

Definition at line 377 of file Dither.cpp.

◆ CONVERT_DIV16

constexpr auto CONVERT_DIV16 = float(1<<15)
constexpr

Definition at line 82 of file Dither.cpp.

Referenced by DITHER_TO_INT16(), and FROM_INT16().

◆ CONVERT_DIV24

constexpr auto CONVERT_DIV24 = float(1<<23)
constexpr

Definition at line 83 of file Dither.cpp.

Referenced by DITHER_TO_INT24(), and FROM_INT24().

◆ intChoicesDither

auto intChoicesDither
static
Initial value:
= {
}
@ rectangle
Definition: Dither.h:20
@ shaped
Definition: Dither.h:20
@ triangle
Definition: Dither.h:20
@ none
Definition: Dither.h:20

Definition at line 383 of file Dither.cpp.

◆ mState

struct State mState

◆ SHAPED_BS

const float SHAPED_BS[] = { 2.033f, -2.165f, 1.959f, -1.590f, 0.6149f }

Definition at line 64 of file Dither.cpp.

Referenced by ShapedDither().