1 #include "Oversampler.hpp"
2 
3 START_NAMESPACE_DISTRHO
4 
Oversampler()5 Oversampler::Oversampler() : fRatio(-1),
6                              fSampleRate(44100),
7                              fNumSamples(512),
8                              fLowPass1(),
9                              fLowPass2(),
10                              fCurrentCapacity(fNumSamples),
11                              fRequiredCapacity(fNumSamples)
12 {
13     fBuffer = (float **)malloc(sizeof(float *) * 2);
14     fBuffer[0] = (float *)malloc(fNumSamples * sizeof(float));
15     fBuffer[1] = (float *)malloc(fNumSamples * sizeof(float));
16 }
17 
~Oversampler()18 Oversampler::~Oversampler()
19 {
20     free(fBuffer[1]);
21     free(fBuffer[0]);
22     free(fBuffer);
23 }
24 
upsample(int ratio,uint32_t numSamples,double sampleRate,const float * const * audio)25 float **Oversampler::upsample(int ratio, uint32_t numSamples, double sampleRate, const float * const *audio)
26 {
27     if (fSampleRate != sampleRate * ratio || fRatio != ratio)
28     {
29         fSampleRate = sampleRate * ratio;
30 
31         fFilterCenter = sampleRate / 2.0f - 4000; //FIXME
32 
33         fLowPass1.reset();
34         fLowPass1.setup(8, fSampleRate, fFilterCenter);
35 
36         fLowPass2.reset();
37         fLowPass2.setup(8, fSampleRate, fFilterCenter);
38     }
39 
40     fRatio = ratio;
41     fNumSamples = numSamples;
42 
43     fRequiredCapacity = numSamples * ratio;
44 
45     if (fCurrentCapacity < fRequiredCapacity)
46     {
47         fBuffer[0] = (float *)realloc(fBuffer[0], fRequiredCapacity * sizeof(float));
48         fBuffer[1] = (float *)realloc(fBuffer[1], fRequiredCapacity * sizeof(float));
49 
50         fCurrentCapacity = fRequiredCapacity;
51     }
52 
53     for (uint32_t i = 0; i < numSamples; ++i)
54     {
55         const int index = i * fRatio; //TODO: find a better name for this variable
56 
57         fBuffer[0][index] = audio[0][i];
58         fBuffer[1][index] = audio[1][i];
59 
60         for (int j = 1; j < fRatio; ++j)
61         {
62             fBuffer[0][index + j] = 0.0f;
63             fBuffer[1][index + j] = 0.0f;
64         }
65     }
66 
67     if (fRatio > 1)
68     {
69         lowPass1();
70         gainBoost();
71     }
72 
73     return fBuffer;
74 }
75 
downsample(float ** targetBuffer)76 void Oversampler::downsample(float **targetBuffer)
77 {
78     if (fRatio > 1)
79         lowPass2();
80 
81     for (uint32_t i = 0; i < fNumSamples; ++i)
82     {
83         targetBuffer[0][i] = fBuffer[0][i * fRatio];
84         targetBuffer[1][i] = fBuffer[1][i * fRatio];
85     }
86 }
87 
lowPass1()88 void Oversampler::lowPass1()
89 {
90     fLowPass1.process(fRequiredCapacity, fBuffer);
91 }
92 
lowPass2()93 void Oversampler::lowPass2()
94 {
95     fLowPass2.process(fRequiredCapacity, fBuffer);
96 }
97 
gainBoost()98 void Oversampler::gainBoost()
99 {
100     for (uint32_t i = 0; i < fRequiredCapacity; ++i)
101     {
102         fBuffer[0][i] *= fRatio;
103         fBuffer[1][i] *= fRatio;
104     }
105 }
106 
107 END_NAMESPACE_DISTRHO