audio: array of reverberators
This commit is contained in:
parent
057ba291d8
commit
91a44e9c5e
7
Makefile
7
Makefile
@ -23,7 +23,9 @@ CFLAGS += -Wno-format
|
||||
CFLAGS += -Wno-error=unused-function
|
||||
CFLAGS += -Wno-error=array-bounds
|
||||
CFLAGS += -Wno-unknown-pragmas
|
||||
ifneq '' '$(findstring clang++,$(CXX))'
|
||||
CFLAGS += -Wno-vla-cxx-extension
|
||||
endif
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += -I./include
|
||||
CFLAGS += -I./data
|
||||
@ -43,7 +45,7 @@ LDFLAGS += -lm
|
||||
#LDFLAGS += -Wl,--gc-sections
|
||||
#-Wl,--print-gc-sections
|
||||
ifeq ($(UNAME),Linux)
|
||||
#LDFLAGS += -Wl,-z noexecstack
|
||||
LDFLAGS += -z noexecstack
|
||||
endif
|
||||
ifeq ($(UNAME),Darwin)
|
||||
LDFLAGS += -framework Foundation -framework Cocoa -framework IOKit -framework AVFoundation -framework CoreVideo -framework CoreAudio -framework CoreMedia -framework CoreHaptics -framework AudioToolbox -framework GameController -framework ForceFeedback -framework Carbon -framework Metal -framework QuartzCore -framework UniformTypeIdentifiers
|
||||
@ -114,9 +116,6 @@ endif
|
||||
|
||||
all: main
|
||||
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(ARCH) $(CSTD) $(CFLAGS) $(FLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
||||
|
||||
|
||||
@ -7,88 +7,57 @@ namespace audio {
|
||||
constexpr int sample_rate = 48000;
|
||||
constexpr int channels = 2;
|
||||
|
||||
template <int maxDelay>
|
||||
struct FeedbackCombFilter {
|
||||
private:
|
||||
//float * buffer;
|
||||
float buffer[maxDelay];
|
||||
int index;
|
||||
public:
|
||||
int delay;
|
||||
float gain0;
|
||||
float gainM;
|
||||
|
||||
FeedbackCombFilter(int delay, float gain0, float gainM);
|
||||
void reset();
|
||||
float feed(float value);
|
||||
};
|
||||
|
||||
template <int maxDelay>
|
||||
struct FeedforwardCombFilter {
|
||||
private:
|
||||
//float * buffer;
|
||||
float buffer[maxDelay];
|
||||
int index;
|
||||
public:
|
||||
int delay;
|
||||
float gain0;
|
||||
float gainM;
|
||||
|
||||
FeedforwardCombFilter(int delay, float gain0, float gainM);
|
||||
void reset();
|
||||
float feed(float value);
|
||||
};
|
||||
|
||||
template <int maxDelay>
|
||||
struct AllpassFilter {
|
||||
private:
|
||||
//float * buffer;
|
||||
float buffer[maxDelay];
|
||||
struct DelayFilter {
|
||||
float * buffer;
|
||||
int index;
|
||||
|
||||
public:
|
||||
const int maxDelay;
|
||||
int delay;
|
||||
float gain0;
|
||||
float gainM;
|
||||
float gain;
|
||||
|
||||
DelayFilter(int maxDelay, int delay, float gain);
|
||||
|
||||
AllpassFilter(int delay, float gain0, float gainM);
|
||||
void reset();
|
||||
float feed(float x);
|
||||
virtual float feed(float value) = 0;
|
||||
};
|
||||
|
||||
using FBCF = FeedbackCombFilter<15000>;
|
||||
using FFCF = FeedforwardCombFilter<15000>;
|
||||
using AP = AllpassFilter<2500>;
|
||||
struct FeedbackCombFilter : DelayFilter {
|
||||
FeedbackCombFilter(int maxDelay, int delay, float gain);
|
||||
float feed(float value) override;
|
||||
};
|
||||
|
||||
struct FeedforwardCombFilter : DelayFilter {
|
||||
public:
|
||||
FeedforwardCombFilter(int maxDelay, int delay, float gain);
|
||||
float feed(float value) override;
|
||||
};
|
||||
|
||||
struct AllpassFilter : DelayFilter {
|
||||
AllpassFilter(int maxDelay, int delay, float gain);
|
||||
float feed(float x) override;
|
||||
};
|
||||
|
||||
using FBCF = FeedbackCombFilter;
|
||||
using FFCF = FeedforwardCombFilter;
|
||||
using AP = AllpassFilter;
|
||||
|
||||
struct lr { float l; float r; };
|
||||
|
||||
struct FBReverb {
|
||||
struct Reverb {
|
||||
static constexpr int apCount = 3;
|
||||
static constexpr int cfCount = 4;
|
||||
static constexpr int apCount = 3;
|
||||
|
||||
FBCF cf[cfCount];
|
||||
AP ap[apCount];
|
||||
DelayFilter * cf;
|
||||
DelayFilter * ap;
|
||||
|
||||
FBReverb();
|
||||
void reset();
|
||||
lr feed(float x);
|
||||
};
|
||||
|
||||
struct FFReverb {
|
||||
static constexpr int __cfCount = 4;
|
||||
static constexpr int apCount = 3;
|
||||
|
||||
FFCF cf[__cfCount];
|
||||
AP ap[apCount];
|
||||
|
||||
FFReverb();
|
||||
Reverb(DelayFilter * cf, DelayFilter * ap);
|
||||
void reset();
|
||||
lr feed(float x);
|
||||
};
|
||||
|
||||
extern int reverbIndex;
|
||||
extern FBReverb fbreverb;
|
||||
extern FFReverb ffreverb;
|
||||
extern Reverb * reverbs[];
|
||||
extern int const reverbsCount;
|
||||
|
||||
extern float wetGain;
|
||||
extern float dryGain;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace ui
|
||||
{
|
||||
void init();
|
||||
void draw(MappedInstanceData<SolidInstance> & data,
|
||||
MappedInstanceData<font::BitmapInstance> & fontData);
|
||||
void update(float mx, float my, bool mLeft, bool mEdge);
|
||||
|
||||
@ -86,6 +86,9 @@ namespace ui::widget
|
||||
T maxExtent;
|
||||
T * value;
|
||||
|
||||
Slider()
|
||||
{}
|
||||
|
||||
Slider(char const * label,
|
||||
int left, int top, int width, int height,
|
||||
T minValue, T maxValue,
|
||||
@ -117,30 +120,27 @@ namespace ui::widget
|
||||
char const * label;
|
||||
|
||||
Slider<int, true> delay;
|
||||
Slider<float, true> gain0;
|
||||
Slider<float, true> gainM;
|
||||
Slider<float, true> gain;
|
||||
|
||||
DelayGainSlider()
|
||||
{}
|
||||
|
||||
DelayGainSlider(char const * label,
|
||||
int left, int top,
|
||||
int delayMin, int delayMax, int * delayValue,
|
||||
float gainMin, float gainMax,
|
||||
float * gain0Value, float * gainMValue)
|
||||
float * gainValue)
|
||||
: label(label)
|
||||
, delay("delay",
|
||||
left, top, 150, 14,
|
||||
delayMin, delayMax,
|
||||
delayMin, delayMax,
|
||||
delayValue)
|
||||
, gain0("gain0",
|
||||
, gain("gain",
|
||||
left, top + 30, 150, 14,
|
||||
gainMin, gainMax,
|
||||
gainMin, gainMax,
|
||||
gain0Value)
|
||||
, gainM("gainM",
|
||||
left, top + 60, 150, 14,
|
||||
gainMin, gainMax,
|
||||
gainMin, gainMax,
|
||||
gainMValue)
|
||||
gainValue)
|
||||
{}
|
||||
|
||||
void draw(MappedInstanceData<SolidInstance> & data,
|
||||
|
||||
208
src/audio.cpp
208
src/audio.cpp
@ -13,14 +13,14 @@
|
||||
#include "poem.h"
|
||||
|
||||
namespace audio {
|
||||
static int const frame_samples = 960; // 20 milliseconds @ 48kHz
|
||||
//static int const frame_samples = 960; // 20 milliseconds @ 48kHz
|
||||
static int const sample_size = (sizeof (int16_t));
|
||||
|
||||
static int const max_frame_size = 960 * 3; // 20ms at 48kHz
|
||||
static int const max_packet_size = 1275;
|
||||
//static int const max_packet_size = 1275;
|
||||
|
||||
static int const half_period_samples = sample_rate / 30;
|
||||
static int const half_period_size = half_period_samples * sample_size * channels;
|
||||
//static int const half_period_size = half_period_samples * sample_size * channels;
|
||||
|
||||
struct AudioBuffer {
|
||||
renpy::language::audio const * audio;
|
||||
@ -28,111 +28,87 @@ namespace audio {
|
||||
uint32_t sample_count;
|
||||
};
|
||||
|
||||
template <int maxDelay>
|
||||
FeedbackCombFilter<maxDelay>::FeedbackCombFilter(int delay, float gain0, float gainM)
|
||||
: delay(delay), gain0(gain0), gainM(gainM)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DelayFilter
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DelayFilter::reset()
|
||||
{
|
||||
//buffer = (float *)malloc((sizeof (float)) * maxDelay);
|
||||
memset(buffer, 0, maxDelay * (sizeof (float)));
|
||||
}
|
||||
|
||||
DelayFilter::DelayFilter(int maxDelay, int delay, float gain)
|
||||
: index(0)
|
||||
, maxDelay(maxDelay)
|
||||
, delay(delay)
|
||||
, gain(gain)
|
||||
{
|
||||
buffer = (float *)malloc(maxDelay * (sizeof (float)));
|
||||
reset();
|
||||
}
|
||||
|
||||
template <int maxDelay>
|
||||
void FeedbackCombFilter<maxDelay>::reset()
|
||||
{
|
||||
index = 0;
|
||||
memset(buffer, 0, (sizeof (float)) * maxDelay);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// FeedbackCombFilter
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <int maxDelay>
|
||||
float FeedbackCombFilter<maxDelay>::feed(float value)
|
||||
FeedbackCombFilter::FeedbackCombFilter(int maxDelay, int delay, float gain)
|
||||
: DelayFilter(maxDelay, delay, gain)
|
||||
{}
|
||||
|
||||
float FeedbackCombFilter::feed(float value)
|
||||
{
|
||||
float y = gain0 * value + gainM * buffer[index];
|
||||
float y = gain * value + gain * buffer[index];
|
||||
buffer[index] = y;
|
||||
index = (index + 1) % delay;
|
||||
return y;
|
||||
}
|
||||
|
||||
template <int maxDelay>
|
||||
FeedforwardCombFilter<maxDelay>::FeedforwardCombFilter(int delay, float gain0, float gainM)
|
||||
: delay(delay), gain0(gain0), gainM(gainM)
|
||||
{
|
||||
//buffer = (float *)malloc((sizeof (float)) * maxDelay);
|
||||
reset();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// FeedForwardCombFilter
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <int maxDelay>
|
||||
void FeedforwardCombFilter<maxDelay>::reset()
|
||||
{
|
||||
index = 0;
|
||||
memset(buffer, 0, (sizeof (float)) * maxDelay);
|
||||
}
|
||||
FeedforwardCombFilter::FeedforwardCombFilter(int maxDelay, int delay, float gain)
|
||||
: DelayFilter(maxDelay, delay, gain)
|
||||
{}
|
||||
|
||||
template <int maxDelay>
|
||||
float FeedforwardCombFilter<maxDelay>::feed(float value)
|
||||
float FeedforwardCombFilter::feed(float value)
|
||||
{
|
||||
float y = gain0 * value + gainM * buffer[index];
|
||||
float y = gain * value + gain * buffer[index];
|
||||
buffer[index] = value;
|
||||
index = (index + 1) % delay;
|
||||
return y;
|
||||
}
|
||||
|
||||
template <int maxDelay>
|
||||
AllpassFilter<maxDelay>::AllpassFilter(int delay, float gain0, float gainM)
|
||||
: delay(delay), gain0(gain0), gainM(gainM)
|
||||
{
|
||||
//buffer = (float *)malloc((sizeof (float)) * maxDelay);
|
||||
reset();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// AllpassFilter
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <int maxDelay>
|
||||
void AllpassFilter<maxDelay>::reset()
|
||||
{
|
||||
index = 0;
|
||||
memset(buffer, 0, (sizeof (float)) * maxDelay);
|
||||
}
|
||||
AllpassFilter::AllpassFilter(int maxDelay, int delay, float gain)
|
||||
: DelayFilter(maxDelay, delay, gain)
|
||||
{}
|
||||
|
||||
template <int maxDelay>
|
||||
float AllpassFilter<maxDelay>::feed(float x)
|
||||
float AllpassFilter::feed(float x)
|
||||
{
|
||||
float v = x + -gainM * buffer[index];
|
||||
float y = buffer[index] + gain0 * v;
|
||||
float v = x + -gain * buffer[index];
|
||||
float y = buffer[index] + gain * v;
|
||||
buffer[index] = v;
|
||||
index = (index + 1) % delay;
|
||||
return y;
|
||||
}
|
||||
|
||||
struct AudioInstance {
|
||||
int audio_index;
|
||||
AudioBuffer * audio_buffer;
|
||||
uint32_t sample_index;
|
||||
uint32_t tail_index;
|
||||
uint32_t fadeout_end;
|
||||
uint32_t fadeout_index;
|
||||
poem::poem const * poem;
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Reverberators
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
FBReverb::FBReverb()
|
||||
: cf{FBCF(3229, 1.0f, 0.733f), // 1687
|
||||
FBCF(3079, 1.0f, 0.802f), // 1601
|
||||
FBCF(3943, 1.0f, 0.753f), // 2053
|
||||
FBCF(4327, 1.0f, 0.733f), // 2251
|
||||
}
|
||||
, ap{AP(661, 0.7f, 0.7f), // 347
|
||||
AP(257, 0.7f, 0.7f), // 113
|
||||
AP(71, 0.7f, 0.7f), // 37
|
||||
}
|
||||
{ }
|
||||
|
||||
void FBReverb::reset()
|
||||
void Reverb::reset()
|
||||
{
|
||||
for (int i = 0; i < cfCount; i++)
|
||||
cf[i].reset();
|
||||
|
||||
for (int i = 0; i < apCount; i++)
|
||||
ap[i].reset();
|
||||
}
|
||||
|
||||
lr FBReverb::feed(float x)
|
||||
lr Reverb::feed(float x)
|
||||
{
|
||||
for (int i = 0; i < apCount; i++) {
|
||||
x = ap[i].feed(x);
|
||||
@ -151,54 +127,54 @@ namespace audio {
|
||||
return {a, b};
|
||||
}
|
||||
|
||||
|
||||
FFReverb::FFReverb()
|
||||
: cf{FFCF{9209, 1.0f, 0.742f},
|
||||
FFCF{9601, 1.0f, 0.733f},
|
||||
FFCF{10369, 1.0f, 0.715f},
|
||||
FFCF{11131, 1.0f, 0.697f},
|
||||
}
|
||||
, ap{AP{2017, 0.7f, 0.7f},
|
||||
AP{647, 0.7f, 0.7f},
|
||||
AP{137, 0.7f, 0.7f},
|
||||
}
|
||||
Reverb::Reverb(DelayFilter * cf, DelayFilter * ap)
|
||||
: cf(cf), ap(ap)
|
||||
{}
|
||||
|
||||
void FFReverb::reset()
|
||||
{
|
||||
for (int i = 0; i < __cfCount; i++) {
|
||||
printf("reset cf %d\n", i);
|
||||
cf[i].reset();
|
||||
}
|
||||
static FFCF forwardCF[4]{FFCF{15000, 9209, 0.742f},
|
||||
FFCF{15000, 9601, 0.733f},
|
||||
FFCF{15000, 10369, 0.715f},
|
||||
FFCF{15000, 11131, 0.697f}};
|
||||
|
||||
for (int i = 0; i < apCount; i++)
|
||||
ap[i].reset();
|
||||
}
|
||||
static AP forwardAP[3]{AP{2500, 2017, 0.7f},
|
||||
AP{2500, 647, 0.7f},
|
||||
AP{2500, 137, 0.7f}};
|
||||
Reverb forwardReverb(forwardCF, forwardAP);
|
||||
|
||||
lr FFReverb::feed(float x)
|
||||
{
|
||||
for (int i = 0; i < apCount; i++) {
|
||||
x = ap[i].feed(x);
|
||||
}
|
||||
|
||||
float x0 = cf[0].feed(x);
|
||||
float x1 = cf[1].feed(x);
|
||||
float x2 = cf[2].feed(x);
|
||||
float x3 = cf[3].feed(x);
|
||||
|
||||
float s0 = x0 + x1 + x2 + x3;
|
||||
//float s0 = x0 + x1 + x2;
|
||||
return {s0, s0};
|
||||
}
|
||||
static FBCF backCF[4]{FBCF{10000, 3229, 0.733f}, // 1687
|
||||
FBCF{10000, 3079, 0.802f}, // 1601
|
||||
FBCF{10000, 3943, 0.753f}, // 2053
|
||||
FBCF{10000, 4327, 0.733f}}; // 2251
|
||||
static AP backAP[3]{AP{1500, 661, 0.7f}, // 347
|
||||
AP{1500, 257, 0.7f}, // 113
|
||||
AP{1500, 71, 0.7f}};
|
||||
Reverb backReverb(backCF, backAP);
|
||||
|
||||
int reverbIndex = 0;
|
||||
FBReverb fbreverb;
|
||||
FFReverb ffreverb;
|
||||
Reverb * reverbs[] = {
|
||||
&backReverb,
|
||||
&forwardReverb,
|
||||
};
|
||||
int const reverbsCount = (sizeof (reverbs)) / (sizeof (reverbs[0]));
|
||||
|
||||
float dryGain = 1.0;
|
||||
float wetGain = 0.25;
|
||||
float mixChannelGain[mixChannelCount];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// AudioInstance
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct AudioInstance {
|
||||
int audio_index;
|
||||
AudioBuffer * audio_buffer;
|
||||
uint32_t sample_index;
|
||||
uint32_t tail_index;
|
||||
uint32_t fadeout_end;
|
||||
uint32_t fadeout_index;
|
||||
poem::poem const * poem;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
static SDL_AudioStream * audio_stream;
|
||||
@ -221,8 +197,8 @@ namespace audio {
|
||||
SDL_ResumeAudioStreamDevice(audio_stream);
|
||||
|
||||
audio_instances_count = 0;
|
||||
fbreverb.reset();
|
||||
ffreverb.reset();
|
||||
for (int i = 0; i < reverbsCount; i++)
|
||||
reverbs[i]->reset();
|
||||
|
||||
for (int i = 0; i < mixChannelCount; i++) {
|
||||
mixChannelGain[i] = 1.0f;
|
||||
@ -566,12 +542,8 @@ namespace audio {
|
||||
float value = channel_buffer[mix_channel::voice][i * channels + 0];
|
||||
|
||||
lr wet;
|
||||
if (reverbIndex == 0) {
|
||||
wet = fbreverb.feed(value);
|
||||
}
|
||||
else {
|
||||
wet = ffreverb.feed(value);
|
||||
}
|
||||
assert(reverbIndex >= 0 && reverbIndex < reverbsCount);
|
||||
wet = reverbs[reverbIndex]->feed(value);
|
||||
float left = value * dryGain + wet.l * wetGain;
|
||||
float right = value * dryGain + wet.r * wetGain;
|
||||
channel_buffer[mix_channel::voice][i * channels + 0] = left;
|
||||
|
||||
@ -1000,6 +1000,12 @@ int main()
|
||||
// 2.17
|
||||
printf("audio_time %f\n", audio_time);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ui
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
ui::init();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// interpreter
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
111
src/ui.cpp
111
src/ui.cpp
@ -12,76 +12,13 @@ namespace ui
|
||||
constexpr int combLeft = 700;
|
||||
constexpr int outputMixLeft = 1000;
|
||||
|
||||
#define BREVERB audio::fbreverb
|
||||
#define FREVERB audio::ffreverb
|
||||
|
||||
widget::DelayGainSlider fap[3] {
|
||||
widget::DelayGainSlider("allpass 0",
|
||||
allpassLeft, top + ySpace * 0,
|
||||
1, 2500, &FREVERB.ap[0].delay,
|
||||
0.0, 1.0, &FREVERB.ap[0].gain0, &FREVERB.ap[0].gainM),
|
||||
widget::DelayGainSlider("allpass 1",
|
||||
allpassLeft, top + ySpace * 1,
|
||||
1, 2500, &FREVERB.ap[1].delay,
|
||||
0.0, 1.0, &FREVERB.ap[1].gain0, &FREVERB.ap[1].gainM),
|
||||
widget::DelayGainSlider("allpass 2",
|
||||
allpassLeft, top + ySpace * 2,
|
||||
1, 2500, &FREVERB.ap[2].delay,
|
||||
0.0, 1.0, &FREVERB.ap[2].gain0, &FREVERB.ap[2].gainM),
|
||||
struct ap_comb {
|
||||
widget::DelayGainSlider ap[3];
|
||||
widget::DelayGainSlider comb[4];
|
||||
};
|
||||
|
||||
widget::DelayGainSlider fcomb[4] {
|
||||
widget::DelayGainSlider("comb 0",
|
||||
combLeft, top + ySpace * 0,
|
||||
100, 15000, &FREVERB.cf[0].delay,
|
||||
0.0, 1.0, &FREVERB.cf[0].gain0, &FREVERB.cf[0].gainM),
|
||||
widget::DelayGainSlider("comb 1",
|
||||
combLeft, top + ySpace * 1,
|
||||
100, 15000, &FREVERB.cf[1].delay,
|
||||
0.0, 1.0, &FREVERB.cf[1].gain0, &FREVERB.cf[1].gainM),
|
||||
widget::DelayGainSlider("comb 2",
|
||||
combLeft, top + ySpace * 2,
|
||||
100, 15000, &FREVERB.cf[2].delay,
|
||||
0.0, 1.0, &FREVERB.cf[2].gain0, &FREVERB.cf[2].gainM),
|
||||
widget::DelayGainSlider("comb 3",
|
||||
combLeft, top + ySpace * 3,
|
||||
100, 15000, &FREVERB.cf[3].delay,
|
||||
0.0, 1.0, &FREVERB.cf[3].gain0, &FREVERB.cf[3].gainM),
|
||||
};
|
||||
|
||||
widget::DelayGainSlider bap[3] {
|
||||
widget::DelayGainSlider("allpass 0",
|
||||
allpassLeft, top + ySpace * 0,
|
||||
1, 2500, &BREVERB.ap[0].delay,
|
||||
0.0, 1.0, &BREVERB.ap[0].gain0, &BREVERB.ap[0].gainM),
|
||||
widget::DelayGainSlider("allpass 1",
|
||||
allpassLeft, top + ySpace * 1,
|
||||
1, 2500, &BREVERB.ap[1].delay,
|
||||
0.0, 1.0, &BREVERB.ap[1].gain0, &BREVERB.ap[1].gainM),
|
||||
widget::DelayGainSlider("allpass 2",
|
||||
allpassLeft, top + ySpace * 2,
|
||||
1, 2500, &BREVERB.ap[2].delay,
|
||||
0.0, 1.0, &BREVERB.ap[2].gain0, &BREVERB.ap[2].gainM),
|
||||
};
|
||||
|
||||
widget::DelayGainSlider bcomb[4] {
|
||||
widget::DelayGainSlider("comb 0",
|
||||
combLeft, top + ySpace * 0,
|
||||
100, 15000, &BREVERB.cf[0].delay,
|
||||
0.0, 1.0, &BREVERB.cf[0].gain0, &BREVERB.cf[0].gainM),
|
||||
widget::DelayGainSlider("comb 1",
|
||||
combLeft, top + ySpace * 1,
|
||||
100, 15000, &BREVERB.cf[1].delay,
|
||||
0.0, 1.0, &BREVERB.cf[1].gain0, &BREVERB.cf[1].gainM),
|
||||
widget::DelayGainSlider("comb 2",
|
||||
combLeft, top + ySpace * 2,
|
||||
100, 15000, &BREVERB.cf[2].delay,
|
||||
0.0, 1.0, &BREVERB.cf[2].gain0, &BREVERB.cf[2].gainM),
|
||||
widget::DelayGainSlider("comb 3",
|
||||
combLeft, top + ySpace * 3,
|
||||
100, 15000, &BREVERB.cf[3].delay,
|
||||
0.0, 1.0, &BREVERB.cf[3].gain0, &BREVERB.cf[3].gainM),
|
||||
};
|
||||
ap_comb reverberatorSliders[2];
|
||||
|
||||
widget::Slider<float, false> dryGain("dry gain",
|
||||
outputMixLeft, top + yMixSpace * 0, 150, 14,
|
||||
@ -118,6 +55,38 @@ namespace ui
|
||||
120, 0,
|
||||
&audio::reverbIndex);
|
||||
|
||||
void init()
|
||||
{
|
||||
static const char * allpassLabels[3] = {
|
||||
"allpass 0",
|
||||
"allpass 1",
|
||||
"allpass 2",
|
||||
};
|
||||
static const char * combLabels[4] = {
|
||||
"comb 0",
|
||||
"comb 1",
|
||||
"comb 2",
|
||||
"comb 3",
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
reverberatorSliders[i].ap[j] =
|
||||
widget::DelayGainSlider(allpassLabels[j],
|
||||
allpassLeft, top + ySpace * j,
|
||||
1, audio::reverbs[i]->ap[j].maxDelay, &audio::reverbs[i]->ap[j].delay,
|
||||
0.0, 1.0, &audio::reverbs[i]->ap[j].gain);
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
reverberatorSliders[i].comb[j] =
|
||||
widget::DelayGainSlider(combLabels[j],
|
||||
combLeft, top + ySpace * j,
|
||||
100, audio::reverbs[i]->cf[j].maxDelay, &audio::reverbs[i]->cf[j].delay,
|
||||
0.0, 1.0, &audio::reverbs[i]->cf[j].gain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(MappedInstanceData<SolidInstance> & data,
|
||||
MappedInstanceData<font::BitmapInstance> & fontData)
|
||||
{
|
||||
@ -127,8 +96,8 @@ namespace ui
|
||||
0x80000000,
|
||||
});
|
||||
|
||||
widget::DelayGainSlider * ap = (audio::reverbIndex == 0) ? bap : fap;
|
||||
widget::DelayGainSlider * comb = (audio::reverbIndex == 0) ? bcomb : fcomb;
|
||||
widget::DelayGainSlider * ap = reverberatorSliders[audio::reverbIndex].ap;
|
||||
widget::DelayGainSlider * comb = reverberatorSliders[audio::reverbIndex].comb;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
ap[i].draw(data, fontData);
|
||||
@ -148,8 +117,8 @@ namespace ui
|
||||
|
||||
void update(float mx, float my, bool mLeft, bool mEdge)
|
||||
{
|
||||
widget::DelayGainSlider * ap = (audio::reverbIndex == 0) ? bap : fap;
|
||||
widget::DelayGainSlider * comb = (audio::reverbIndex == 0) ? bcomb : fcomb;
|
||||
widget::DelayGainSlider * ap = reverberatorSliders[audio::reverbIndex].ap;
|
||||
widget::DelayGainSlider * comb = reverberatorSliders[audio::reverbIndex].comb;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
ap[i].update(mx, my, mLeft, mEdge);
|
||||
|
||||
@ -179,15 +179,13 @@ namespace ui::widget
|
||||
drawStringCentered(fontData, delay.slider.left + delay.slider.width / 2, delay.slider.top - 16, label);
|
||||
|
||||
delay.draw(data, fontData);
|
||||
gain0.draw(data, fontData);
|
||||
gainM.draw(data, fontData);
|
||||
gain.draw(data, fontData);
|
||||
}
|
||||
|
||||
void DelayGainSlider::update(float mx, float my, bool mLeft, bool mEdge)
|
||||
{
|
||||
delay.update(mx, my, mLeft, mEdge);
|
||||
gain0.update(mx, my, mLeft, mEdge);
|
||||
gainM.update(mx, my, mLeft, mEdge);
|
||||
gain.update(mx, my, mLeft, mEdge);
|
||||
}
|
||||
|
||||
template <int optionCount>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user