Coverage Report

Created: 2026-02-26 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpg123/src/libmpg123/dither_impl.h
Line
Count
Source
1
/*
2
  dither: Generate shaped noise for dithering
3
4
  copyright 2009 by the mpg123 project - free software under the terms of the LGPL 2.1
5
  see COPYING and AUTHORS files in distribution or http://mpg123.org
6
  initially written by Taihei Monma
7
*/
8
9
#include "config.h"
10
#include "../compat/compat.h"
11
#include "dither.h"
12
13
static const uint32_t init_seed = 2463534242UL;
14
15
0
#define LAP 100
16
17
/*
18
  xorshift random number generator, with output scaling to [-0.5, 0.5]
19
  This is the white noise...
20
  See http://www.jstatsoft.org/v08/i14/paper on XOR shift random number generators.
21
*/
22
static float rand_xorshift32(uint32_t *seed)
23
0
{
24
0
  union
25
0
  {
26
0
    uint32_t i;
27
0
    float f;
28
0
  } fi;
29
  
30
0
  fi.i = *seed;
31
0
  fi.i ^= (fi.i<<13);
32
0
  fi.i ^= (fi.i>>17);
33
0
  fi.i ^= (fi.i<<5);
34
0
  *seed = fi.i;
35
  
36
  /* scale the number to [-0.5, 0.5] */
37
0
#ifdef IEEE_FLOAT
38
0
  fi.i = (fi.i>>9)|0x3f800000;
39
0
  fi.f -= 1.5f;
40
#else
41
  fi.f = (double)fi.i / 4294967295.0;
42
  fi.f -= 0.5f;
43
#endif
44
0
  return fi.f;
45
0
}
46
47
static void white_noise(float *table, size_t count)
48
0
{
49
0
  size_t i;
50
0
  uint32_t seed = init_seed;
51
  
52
0
  for(i=0; i<count; ++i)
53
0
  table[i] = rand_xorshift32(&seed);
54
0
}
55
56
static void tpdf_noise(float *table, size_t count)
57
0
{
58
0
  size_t i;
59
0
  uint32_t seed = init_seed;
60
  
61
0
  for(i=0; i<count; ++i)
62
0
  table[i] = rand_xorshift32(&seed) + rand_xorshift32(&seed);
63
0
}
64
65
static void highpass_tpdf_noise(float *table, size_t count)
66
0
{
67
0
  size_t i;
68
0
  uint32_t seed = init_seed;
69
  /* Ensure some minimum lap for keeping the high-pass filter circular. */
70
0
  size_t lap = count > 2*LAP ? LAP : count/2;
71
72
0
  float input_noise;
73
0
  float xv[9], yv[9];
74
75
0
  for(i=0;i<9;i++)
76
0
  {
77
0
    xv[i] = yv[i] = 0.0f;
78
0
  }
79
80
0
  for(i=0;i<count+lap;i++)
81
0
  {
82
0
    if(i==count) seed=init_seed;
83
    
84
    /* generate and add 2 random numbers, to make a TPDF noise distribution */
85
0
    input_noise = rand_xorshift32(&seed) + rand_xorshift32(&seed);
86
87
    /* apply 8th order Chebyshev high-pass IIR filter */
88
    /* Coefficients are from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
89
       Given parameters are: Chebyshev, Highpass, ripple=-1, order=8, samplerate=44100, corner1=19000 */
90
0
    xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; 
91
0
    xv[8] = input_noise / 1.382814179e+07;
92
0
    yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; 
93
0
    yv[8] = (xv[0] + xv[8]) - 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6])
94
0
        - 56 * (xv[3] + xv[5]) + 70 * xv[4]
95
0
        + ( -0.6706204984 * yv[0]) + ( -5.3720827038 * yv[1])
96
0
        + (-19.0865382480 * yv[2]) + (-39.2831607860 * yv[3])
97
0
        + (-51.2308985070 * yv[4]) + (-43.3590135780 * yv[5])
98
0
        + (-23.2632305320 * yv[6]) + ( -7.2370122050 * yv[7]);
99
0
    if(i>=lap) table[i-lap] = yv[8] * 3.0f;
100
0
  }
101
0
}
102
103
void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype)
104
0
{
105
0
  switch(noisetype)
106
0
  {
107
0
    case mpg123_white_noise: white_noise(table, count); break;
108
0
    case mpg123_tpdf_noise:  tpdf_noise(table, count);  break;
109
0
    case mpg123_highpass_tpdf_noise:
110
0
      highpass_tpdf_noise(table, count);
111
0
    break;
112
0
  }
113
0
}
114
115
/* Generate white noise and shape it with a high pass filter. */
116
void INT123_dither_table_init(float *dithertable)
117
0
{
118
0
  highpass_tpdf_noise(dithertable, DITHERSIZE);
119
0
}