Process a single bank.
42 Size actuallyRendered = 0;
44 manager.forEachVoice([&](Voice& v,
Size index) {
45 if (v.bank != bank.id) {
return true; }
46 if (v.spatialized) {
return true; }
49 auto& source = bank.sources[v.source];
50 auto& signal = source.signal;
54 if (signalLength == 0) {
return false; }
55 if (signal.sampleRate != sampleRate) {
60 v.time = v.time % signalLength;
62 const auto signalChannels = signal.channels();
63 auto& mixer = bank.mixers[v.mixer];
64 auto& target = mixer.buffer;
65 const auto targetChannels = target.channels();
66 const auto gain = v.gain * source.gain;
71 auto& pan = manager.getVoicePan(index);
72 target.setValidSize(frames);
81 for (
int c = 0; c < targetChannels; c++) {
82 const int channel = c % signalChannels;
85 signal[channel][((v.time + s) % signalLength)] * gain * pan.volumes[c];
91 for (
int c = 0; c < targetChannels; c++) {
93 const int channel = c % signalChannels;
95 signal[channel][v.time + s] * gain * pan.volumes[c];
100 v.time = v.time + frames;
101 return needed == frames;
107 auto& fd = manager.getVoiceFilter(index);
112 fd.highpassScratch[c] = 0;
113 fd.lowpassScratch[c] = signal[c % signalChannels][v.time];
122 const Real speed = fd.speed * (
Sample(signal.sampleRate) /
Sample(sampleRate));
124 frames,
SampleIndex(std::floor((signalLength - v.time) / speed - fd.timeFract))
127 for (
int c = 0; c < target.channels(); c++) {
129 const int channel = c % signal.channels();
131 position = v.time + (s * speed) + fd.timeFract;
132 const Real lastPosition = std::floor(position);
133 const Size lastIndex = (
Size) lastPosition;
134 const Size nextIndex = (
Size) lastPosition + 1;
136 Real mix = position - lastPosition;
138 const Sample last = signal[channel][lastIndex % signalLength] * gain;
139 const Sample next = signal[channel][nextIndex % signalLength] * gain;
141 const Sample in = last +
mix * (next - last);
145 const Sample lf = fd.lowpass;
146 const Sample lpd = in + lf * (fd.lowpassScratch[c] - in);
147 fd.lowpassScratch[c] = lpd;
149 const Sample hf = fd.highpass;
150 const Sample hps = fd.highpassScratch[c];
151 const Sample hpd = hps + hf * (in - hps);
152 fd.highpassScratch[c] = hpd;
154 target[c][s] += (lpd - hpd) * pan.volumes[c];
159 fd.timeFract = position - v.time;
160 return needed == frames;
163 return actuallyRendered;
Size mix(VoiceManger &manager, Bank &bank, SampleIndex frames, Size sampleRate)
Process a single bank.
T min(const T &v1, const T &v2)
AudioBuffer::Size SampleIndex
unsigned int Size
How the elements are addressed in the heapbuffer.
float Sample
Default sample types used where ever possible, changing this means the engine needs to be recompiled,...
#define VAE_PROFILER_SCOPE_NAMED(name)
Profiles a scope and names it.