Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/dsp/core.hpp
2 views
1
#ifdef NALL_DSP_INTERNAL_HPP
2
3
#include <math.h>
4
#include <nall/stdint.hpp>
5
6
namespace nall {
7
8
//precision: can be float, double or long double
9
#define real float
10
11
struct DSP;
12
13
struct Resampler {
14
DSP &dsp;
15
real frequency;
16
17
virtual void setFrequency() = 0;
18
virtual void clear() = 0;
19
virtual void sample() = 0;
20
Resampler(DSP &dsp) : dsp(dsp) {}
21
};
22
23
struct DSP {
24
enum class ResampleEngine : unsigned {
25
Nearest,
26
Linear,
27
Cosine,
28
Cubic,
29
Hermite,
30
Average,
31
Sinc,
32
};
33
34
inline void setChannels(unsigned channels);
35
inline void setPrecision(unsigned precision);
36
inline void setFrequency(real frequency); //inputFrequency
37
inline void setVolume(real volume);
38
inline void setBalance(real balance);
39
40
inline void setResampler(ResampleEngine resamplingEngine);
41
inline void setResamplerFrequency(real frequency); //outputFrequency
42
43
inline void sample(signed channel[]);
44
inline bool pending();
45
inline void read(signed channel[]);
46
47
inline void clear();
48
inline DSP();
49
inline ~DSP();
50
51
protected:
52
friend class ResampleNearest;
53
friend class ResampleLinear;
54
friend class ResampleCosine;
55
friend class ResampleCubic;
56
friend class ResampleAverage;
57
friend class ResampleHermite;
58
friend class ResampleSinc;
59
60
struct Settings {
61
unsigned channels;
62
unsigned precision;
63
real frequency;
64
real volume;
65
real balance;
66
67
//internal
68
real intensity;
69
real intensityInverse;
70
} settings;
71
72
Resampler *resampler;
73
inline void write(real channel[]);
74
75
#include "buffer.hpp"
76
Buffer buffer;
77
Buffer output;
78
79
inline void adjustVolume();
80
inline void adjustBalance();
81
inline signed clamp(const unsigned bits, const signed x);
82
};
83
84
#include "resample/nearest.hpp"
85
#include "resample/linear.hpp"
86
#include "resample/cosine.hpp"
87
#include "resample/cubic.hpp"
88
#include "resample/hermite.hpp"
89
#include "resample/average.hpp"
90
#include "resample/sinc.hpp"
91
#include "settings.hpp"
92
93
void DSP::sample(signed channel[]) {
94
for(unsigned c = 0; c < settings.channels; c++) {
95
buffer.write(c) = (real)channel[c] * settings.intensityInverse;
96
}
97
buffer.wroffset++;
98
resampler->sample();
99
}
100
101
bool DSP::pending() {
102
return output.rdoffset != output.wroffset;
103
}
104
105
void DSP::read(signed channel[]) {
106
adjustVolume();
107
adjustBalance();
108
109
for(unsigned c = 0; c < settings.channels; c++) {
110
channel[c] = clamp(settings.precision, output.read(c) * settings.intensity);
111
}
112
output.rdoffset++;
113
}
114
115
void DSP::write(real channel[]) {
116
for(unsigned c = 0; c < settings.channels; c++) {
117
output.write(c) = channel[c];
118
}
119
output.wroffset++;
120
}
121
122
void DSP::adjustVolume() {
123
for(unsigned c = 0; c < settings.channels; c++) {
124
output.read(c) *= settings.volume;
125
}
126
}
127
128
void DSP::adjustBalance() {
129
if(settings.channels != 2) return; //TODO: support > 2 channels
130
if(settings.balance < 0.0) output.read(1) *= 1.0 + settings.balance;
131
if(settings.balance > 0.0) output.read(0) *= 1.0 - settings.balance;
132
}
133
134
signed DSP::clamp(const unsigned bits, const signed x) {
135
const signed b = 1U << (bits - 1);
136
const signed m = (1U << (bits - 1)) - 1;
137
return (x > m) ? m : (x < -b) ? -b : x;
138
}
139
140
void DSP::clear() {
141
buffer.clear();
142
output.clear();
143
resampler->clear();
144
}
145
146
DSP::DSP() {
147
setResampler(ResampleEngine::Hermite);
148
setResamplerFrequency(44100.0);
149
150
setChannels(2);
151
setPrecision(16);
152
setFrequency(44100.0);
153
setVolume(1.0);
154
setBalance(0.0);
155
156
clear();
157
}
158
159
DSP::~DSP() {
160
if(resampler) delete resampler;
161
}
162
163
#undef real
164
165
}
166
167
#endif
168
169