Named Effect parameters added. Unsupported effects disabled.

Unnamed parameter Effect setting is no longer functional.

--HG--
branch : minor
This commit is contained in:
Raidho
2017-01-06 08:41:27 +03:00
parent 9fd53ad46f
commit 42f89153ae
10 changed files with 683 additions and 322 deletions
+4 -6
View File
@@ -211,11 +211,10 @@ public:
/**
* Sets scene EFX effect.
* @param slot Slot to put effect into.
* @param type Effect type to use.
* @param params Effect description table.
* @param fxparams Effect description table.
* @return true if successful, false otherwise.
*/
virtual bool setSceneEffect(int slot, Effect::Type type, std::vector<float> &params) = 0;
virtual bool setSceneEffect(int slot, std::map<Effect::Parameter, float> &params) = 0;
/**
* Removes scene EFX effect.
@@ -227,11 +226,10 @@ public:
/**
* Gets scene EFX effect.
* @param slot Slot from which to get effect.
* @param type Effect type.
* @param params Effect description table.
* @param fxparams Effect description table.
* @return true if effect was present, false otherwise.
*/
virtual bool getSceneEffect(int slot, Effect::Type &type, std::vector<float> &params) = 0;
virtual bool getSceneEffect(int slot, std::map<Effect::Parameter, float> &params) = 0;
/**
* Gets maximum number of scene EFX effects.
+235 -35
View File
@@ -47,7 +47,7 @@ bool Effect::getConstant(Type in, const char *&out)
{
return types.find(in, out);
}
/*
bool Effect::getConstant(const char *in, Phoneme &out)
{
return phonemes.find(in, out);
@@ -57,7 +57,7 @@ bool Effect::getConstant(Phoneme in, const char *&out)
{
return phonemes.find(in, out);
}
*/
bool Effect::getConstant(const char *in, Waveform &out)
{
return waveforms.find(in, out);
@@ -67,7 +67,7 @@ bool Effect::getConstant(Waveform in, const char *&out)
{
return waveforms.find(in, out);
}
/*
bool Effect::getConstant(const char *in, Direction &out)
{
return directions.find(in, out);
@@ -77,8 +77,18 @@ bool Effect::getConstant(Direction in, const char *&out)
{
return directions.find(in, out);
}
*/
bool Effect::getConstant(const char *in, Parameter &out, Type t)
{
return parameterNames[t].find(in, out);
}
const std::vector<Effect::ParameterType> &Effect::getParameterTypes(Effect::Type in)
bool Effect::getConstant(Parameter in, const char *&out, Type t)
{
return parameterNames[t].find(in, out);
}
Effect::ParameterType Effect::getParameterType(Effect::Parameter in)
{
return parameterTypes[in];
}
@@ -90,11 +100,11 @@ StringMap<Effect::Type, Effect::TYPE_MAX_ENUM>::Entry Effect::typeEntries[] =
{"distortion", Effect::TYPE_DISTORTION},
{"echo", Effect::TYPE_ECHO},
{"flanger", Effect::TYPE_FLANGER},
{"frequencyshifter", Effect::TYPE_FREQSHIFTER},
{"vocalmorpher", Effect::TYPE_MORPHER},
{"pitchshifter", Effect::TYPE_PITCHSHIFTER},
//{"frequencyshifter", Effect::TYPE_FREQSHIFTER},
//{"vocalmorpher", Effect::TYPE_MORPHER},
//{"pitchshifter", Effect::TYPE_PITCHSHIFTER},
{"ringmodulator", Effect::TYPE_MODULATOR},
{"autowah", Effect::TYPE_AUTOWAH},
//{"autowah", Effect::TYPE_AUTOWAH},
{"compressor", Effect::TYPE_COMPRESSOR},
{"equalizer", Effect::TYPE_EQUALIZER},
};
@@ -111,6 +121,7 @@ StringMap<Effect::Waveform, Effect::WAVE_MAX_ENUM>::Entry Effect::waveformEntrie
StringMap<Effect::Waveform, Effect::WAVE_MAX_ENUM> Effect::waveforms(Effect::waveformEntries, sizeof(Effect::waveformEntries));
/*
StringMap<Effect::Direction, Effect::DIR_MAX_ENUM>::Entry Effect::directionEntries[] =
{
{"up", Effect::DIR_UP},
@@ -155,35 +166,224 @@ StringMap<Effect::Phoneme, Effect::PHONEME_MAX_ENUM>::Entry Effect::phonemeEntri
};
StringMap<Effect::Phoneme, Effect::PHONEME_MAX_ENUM> Effect::phonemes(Effect::phonemeEntries, sizeof(Effect::phonemeEntries));
*/
std::map<Effect::Type, std::vector<Effect::ParameterType>> Effect::parameterTypes =
#define StringMap LazierAndSlowerButEasilyArrayableStringMap
std::vector<StringMap<Effect::Parameter>::Entry> Effect::basicParameters =
{
//gain, high gain, density, diffusion, decay, high decay ratio, refl gain, refl delay, late gain, late delay, rolloff, air high gain, high limiter
{Effect::TYPE_REVERB, {Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT,
Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_BOOL}},
//waveform, phase, rate, depth, feedback, delay
{Effect::TYPE_CHORUS, { Effect::PAR_WAVEFORM, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
//gain, edge, lowpass cutoff, eq center, eq width
{Effect::TYPE_DISTORTION, {Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
//delay, LR delay, damping, feedback, spread
{Effect::TYPE_ECHO, {Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
//waveform, phase, rate, depth, feedback, delay
{Effect::TYPE_FLANGER, {Effect::PAR_WAVEFORM, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
//frequency, left direction, right direction
{Effect::TYPE_FREQSHIFTER, {Effect::PAR_FLOAT, Effect::PAR_DIRECTION, Effect::PAR_DIRECTION}},
//waveform, rate, phoneme A, phoneme B, phoneme A coarse tune, phoneme B coarse tune
{Effect::TYPE_MORPHER, {Effect::PAR_WAVEFORM, Effect::PAR_FLOAT, Effect::PAR_PHONEME, Effect::PAR_PHONEME, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
//pitch(semitones)
{Effect::TYPE_PITCHSHIFTER, {Effect::PAR_FLOAT}},
//waveform, frequency, highpass cutoff
{Effect::TYPE_MODULATOR, {Effect::PAR_WAVEFORM, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
//attack, release, resonance, peak gain
{Effect::TYPE_AUTOWAH, {Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
// on-off switch
{Effect::TYPE_COMPRESSOR, {Effect::PAR_BOOL}},
//low gain, low cut, mid1 gain, mid1 freq, mid1 band, mid2 gain, mid2 freq, mid2 band, high gain, high cut
{Effect::TYPE_EQUALIZER, {Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT,
Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT, Effect::PAR_FLOAT}},
{"type", Effect::EFFECT_TYPE},
{"volume", Effect::EFFECT_VOLUME}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::reverbParameters =
{
{"gain", Effect::REVERB_GAIN},
{"hfgain", Effect::REVERB_HFGAIN},
{"density", Effect::REVERB_DENSITY},
{"diffusion", Effect::REVERB_DIFFUSION},
{"decay", Effect::REVERB_DECAY},
{"hfdecay", Effect::REVERB_HFDECAY},
{"earlygain", Effect::REVERB_EARLYGAIN},
{"earlydelay", Effect::REVERB_EARLYDELAY},
{"lategain", Effect::REVERB_LATEGAIN},
{"latedelay", Effect::REVERB_LATEDELAY},
{"rolloff", Effect::REVERB_ROLLOFF},
{"airhfgain", Effect::REVERB_AIRHFGAIN},
{"hflimiter", Effect::REVERB_HFLIMITER}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::chorusParameters =
{
{"waveform", Effect::CHORUS_WAVEFORM},
{"phase", Effect::CHORUS_PHASE},
{"rate", Effect::CHORUS_RATE},
{"depth", Effect::CHORUS_DEPTH},
{"feedback", Effect::CHORUS_FEEDBACK},
{"delay", Effect::CHORUS_DELAY}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::distortionParameters =
{
{"gain", Effect::DISTORTION_GAIN},
{"edge", Effect::DISTORTION_EDGE},
{"lowcut", Effect::DISTORTION_LOWCUT},
{"eqcenter", Effect::DISTORTION_EQCENTER},
{"eqbandwidth", Effect::DISTORTION_EQBAND}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::echoParameters =
{
{"delay", Effect::ECHO_DELAY},
{"lrdelay", Effect::ECHO_LRDELAY},
{"damping", Effect::ECHO_DAMPING},
{"feedback", Effect::ECHO_FEEDBACK},
{"spread", Effect::ECHO_SPREAD}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::flangerParameters =
{
{"waveform", Effect::FLANGER_WAVEFORM},
{"phase", Effect::FLANGER_PHASE},
{"rate", Effect::FLANGER_RATE},
{"depth", Effect::FLANGER_DEPTH},
{"feedback", Effect::FLANGER_FEEDBACK},
{"delay", Effect::FLANGER_DELAY}
};
/*
std::vector<StringMap<Effect::Parameter>::Entry> Effect::freqshifterParameters =
{
{"frequency", Effect::FREQSHIFTER_FREQ},
{"leftdirection", Effect::FREQSHIFTER_LEFTDIR},
{"rightdirection", Effect::FREQSHIFTER_RIGHTDIR}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::morpherParameters =
{
{"waveform", Effect::MORPHER_WAVEFORM},
{"rate", Effect::MORPHER_RATE},
{"phonemea", Effect::MORPHER_PHONEMEA},
{"phonemeb", Effect::MORPHER_PHONEMEB},
{"tunea", Effect::MORPHER_COARSEA},
{"tuneb", Effect::MORPHER_COARSEB}
}
;
std::vector<StringMap<Effect::Parameter>::Entry> Effect::pitchshifterParameters =
{
{"pitch", Effect::PITCHSHIFTER_PITCH}
};
*/
std::vector<StringMap<Effect::Parameter>::Entry> Effect::modulatorParameters =
{
{"waveform", Effect::MODULATOR_WAVEFORM},
{"frequency", Effect::MODULATOR_FREQ},
{"highcut", Effect::MODULATOR_HIGHCUT}
};
/*
std::vector<StringMap<Effect::Parameter>::Entry> Effect::autowahParameters =
{
{"attack", Effect::AUTOWAH_ATTACK},
{"release", Effect::AUTOWAH_RELEASE},
{"resonance", Effect::AUTOWAH_RESONANCE},
{"peakgain", Effect::AUTOWAH_PEAKGAIN}
};
*/
std::vector<StringMap<Effect::Parameter>::Entry> Effect::compressorParameters =
{
{"enable", Effect::COMPRESSOR_ENABLE}
};
std::vector<StringMap<Effect::Parameter>::Entry> Effect::equalizerParameters =
{
{"lowgain", Effect::EQUALIZER_LOWGAIN},
{"lowcut", Effect::EQUALIZER_LOWCUT},
{"mid1gain", Effect::EQUALIZER_MID1GAIN},
{"mid1frequency", Effect::EQUALIZER_MID1FREQ},
{"mid1bandwidth", Effect::EQUALIZER_MID1BAND},
{"mid2gain", Effect::EQUALIZER_MID2GAIN},
{"mid2frequency", Effect::EQUALIZER_MID2FREQ},
{"mid2bandwidth", Effect::EQUALIZER_MID2BAND},
{"highgain", Effect::EQUALIZER_HIGHGAIN},
{"highcut", Effect::EQUALIZER_HIGHCUT}
};
std::map<Effect::Type, StringMap<Effect::Parameter>> Effect::parameterNames =
{
{Effect::TYPE_BASIC, Effect::basicParameters},
{Effect::TYPE_REVERB, Effect::reverbParameters},
{Effect::TYPE_CHORUS, Effect::chorusParameters},
{Effect::TYPE_DISTORTION, Effect::distortionParameters},
{Effect::TYPE_ECHO, Effect::echoParameters},
{Effect::TYPE_FLANGER, Effect::flangerParameters},
//{Effect::TYPE_FREQSHIFTER, Effect::freqshifterParameters},
//{Effect::TYPE_MORPHER, Effect::morpherbParameters},
//{Effect::TYPE_PITCHSHIFTER, Effect::pitchshifterParameters},
{Effect::TYPE_MODULATOR, Effect::modulatorParameters},
//{Effect::TYPE_AUTOWAH, Effect::autowahParameters},
{Effect::TYPE_COMPRESSOR, Effect::compressorParameters},
{Effect::TYPE_EQUALIZER, Effect::equalizerParameters}
};
#undef StringMap
std::map<Effect::Parameter, Effect::ParameterType> Effect::parameterTypes =
{
{Effect::EFFECT_TYPE, Effect::PARAM_TYPE},
{Effect::EFFECT_VOLUME, Effect::PARAM_FLOAT},
{Effect::REVERB_GAIN, Effect::PARAM_FLOAT},
{Effect::REVERB_HFGAIN, Effect::PARAM_FLOAT},
{Effect::REVERB_DENSITY, Effect::PARAM_FLOAT},
{Effect::REVERB_DIFFUSION, Effect::PARAM_FLOAT},
{Effect::REVERB_DECAY, Effect::PARAM_FLOAT},
{Effect::REVERB_HFDECAY, Effect::PARAM_FLOAT},
{Effect::REVERB_EARLYGAIN, Effect::PARAM_FLOAT},
{Effect::REVERB_EARLYDELAY, Effect::PARAM_FLOAT},
{Effect::REVERB_LATEGAIN, Effect::PARAM_FLOAT},
{Effect::REVERB_LATEDELAY, Effect::PARAM_FLOAT},
{Effect::REVERB_ROLLOFF, Effect::PARAM_FLOAT},
{Effect::REVERB_AIRHFGAIN, Effect::PARAM_FLOAT},
{Effect::REVERB_HFLIMITER, Effect::PARAM_BOOL},
{Effect::CHORUS_WAVEFORM, Effect::PARAM_WAVEFORM},
{Effect::CHORUS_PHASE, Effect::PARAM_FLOAT},
{Effect::CHORUS_RATE, Effect::PARAM_FLOAT},
{Effect::CHORUS_DEPTH, Effect::PARAM_FLOAT},
{Effect::CHORUS_FEEDBACK, Effect::PARAM_FLOAT},
{Effect::CHORUS_DELAY, Effect::PARAM_FLOAT},
{Effect::DISTORTION_GAIN, Effect::PARAM_FLOAT},
{Effect::DISTORTION_EDGE, Effect::PARAM_FLOAT},
{Effect::DISTORTION_LOWCUT, Effect::PARAM_FLOAT},
{Effect::DISTORTION_EQCENTER, Effect::PARAM_FLOAT},
{Effect::DISTORTION_EQBAND, Effect::PARAM_FLOAT},
{Effect::ECHO_DELAY, Effect::PARAM_FLOAT},
{Effect::ECHO_LRDELAY, Effect::PARAM_FLOAT},
{Effect::ECHO_DAMPING, Effect::PARAM_FLOAT},
{Effect::ECHO_FEEDBACK, Effect::PARAM_FLOAT},
{Effect::ECHO_SPREAD, Effect::PARAM_FLOAT},
{Effect::FLANGER_WAVEFORM, Effect::PARAM_WAVEFORM},
{Effect::FLANGER_PHASE, Effect::PARAM_FLOAT},
{Effect::FLANGER_RATE, Effect::PARAM_FLOAT},
{Effect::FLANGER_DEPTH, Effect::PARAM_FLOAT},
{Effect::FLANGER_FEEDBACK, Effect::PARAM_FLOAT},
{Effect::FLANGER_DELAY, Effect::PARAM_FLOAT},
/*
{Effect::FREQSHIFTER_FREQ, Effect::PARAM_FLOAT},
{Effect::FREQSHIFTER_LEFTDIR, Effect::PARAM_DIRECTION},
{Effect::FREQSHIFTER_RIGHTDIR, Effect::PARAM_DIRECTION},
{Effect::MORPHER_WAVEFORM, Effect::PARAM_WAVEFORM},
{Effect::MORPHER_RATE, Effect::PARAM_FLOAT},
{Effect::MORPHER_PHONEMEA, Effect::PARAM_PHONEME},
{Effect::MORPHER_PHONEMEB, Effect::PARAM_PHONEME},
{Effect::MORPHER_TUNEA, Effect::PARAM_FLOAT},
{Effect::MORPHER_TUNEB, Effect::PARAM_FLOAT},
{Effect::PITCHSHIFTER_PITCH, Effect::PARAM_FLOAT},
*/
{Effect::MODULATOR_WAVEFORM, Effect::PARAM_WAVEFORM},
{Effect::MODULATOR_FREQ, Effect::PARAM_FLOAT},
{Effect::MODULATOR_HIGHCUT, Effect::PARAM_FLOAT},
/*
{Effect::AUTOWAH_ATTACK, Effect::PARAM_FLOAT},
{Effect::AUTOWAH_RELEASE, Effect::PARAM_FLOAT},
{Effect::AUTOWAH_RESONANCE, Effect::PARAM_FLOAT},
{Effect::AUTOWAH_PEAKGAIN, Effect::PARAM_FLOAT},
*/
{Effect::COMPRESSOR_ENABLE, Effect::PARAM_BOOL},
{Effect::EQUALIZER_LOWGAIN, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_LOWCUT, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_MID1GAIN, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_MID1FREQ, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_MID1BAND, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_MID2GAIN, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_MID2FREQ, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_MID2BAND, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_HIGHGAIN, Effect::PARAM_FLOAT},
{Effect::EQUALIZER_HIGHCUT, Effect::PARAM_FLOAT}
};
} //audio
+169 -21
View File
@@ -26,6 +26,49 @@
#include <map>
#include <vector>
template<typename T>
class LazierAndSlowerButEasilyArrayableStringMap
{
public:
struct Entry
{
const char *key;
T value;
};
LazierAndSlowerButEasilyArrayableStringMap()
{
}
LazierAndSlowerButEasilyArrayableStringMap(const std::vector<Entry> &entries)
{
for (auto entry : entries)
{
forward[entry.key] = entry.value;
reverse[entry.value] = entry.key;
}
}
bool find(const char *key, T &t)
{
if (forward.find(key) == forward.end())
return false;
t = forward[key];
return true;
}
bool find(T key, const char *&str)
{
if (reverse.find(key) == reverse.end())
return false;
str = reverse[key];
return true;
}
private:
std::map<std::string, T> forward;
std::map<T, const char*> reverse;
};
namespace love
{
namespace audio
@@ -36,29 +79,114 @@ class Effect
public:
enum Type
{
TYPE_BASIC, //not a real type
TYPE_REVERB,
TYPE_CHORUS,
TYPE_DISTORTION,
TYPE_ECHO,
TYPE_FLANGER,
TYPE_FREQSHIFTER,
TYPE_MORPHER,
TYPE_PITCHSHIFTER,
//TYPE_FREQSHIFTER,
//TYPE_MORPHER,
//TYPE_PITCHSHIFTER,
TYPE_MODULATOR,
TYPE_AUTOWAH,
//TYPE_AUTOWAH,
TYPE_COMPRESSOR,
TYPE_EQUALIZER,
TYPE_MAX_ENUM
};
enum Parameter
{
EFFECT_TYPE,
EFFECT_VOLUME,
REVERB_GAIN,
REVERB_HFGAIN,
REVERB_DENSITY,
REVERB_DIFFUSION,
REVERB_DECAY,
REVERB_HFDECAY,
REVERB_EARLYGAIN,
REVERB_EARLYDELAY,
REVERB_LATEGAIN,
REVERB_LATEDELAY,
REVERB_ROLLOFF,
REVERB_AIRHFGAIN,
REVERB_HFLIMITER,
CHORUS_WAVEFORM,
CHORUS_PHASE,
CHORUS_RATE,
CHORUS_DEPTH,
CHORUS_FEEDBACK,
CHORUS_DELAY,
DISTORTION_GAIN,
DISTORTION_EDGE,
DISTORTION_LOWCUT,
DISTORTION_EQCENTER,
DISTORTION_EQBAND,
ECHO_DELAY,
ECHO_LRDELAY,
ECHO_DAMPING,
ECHO_FEEDBACK,
ECHO_SPREAD,
FLANGER_WAVEFORM,
FLANGER_PHASE,
FLANGER_RATE,
FLANGER_DEPTH,
FLANGER_FEEDBACK,
FLANGER_DELAY,
/*
FREQSHIFTER_FREQ,
FREQSHIFTER_LEFTDIR,
FREQSHIFTER_RIGHTDIR,
MORPHER_WAVEFORM,
MORPHER_RATE,
MORPHER_PHONEMEA,
MORPHER_PHONEMEB,
MORPHER_TUNEA,
MORPHER_TUNEB,
PITCHSHIFTER_PITCH,
*/
MODULATOR_WAVEFORM,
MODULATOR_FREQ,
MODULATOR_HIGHCUT,
/*
AUTOWAH_ATTACK,
AUTOWAH_RELEASE,
AUTOWAH_RESONANCE,
AUTOWAH_PEAKGAIN,
*/
COMPRESSOR_ENABLE,
EQUALIZER_LOWGAIN,
EQUALIZER_LOWCUT,
EQUALIZER_MID1GAIN,
EQUALIZER_MID1FREQ,
EQUALIZER_MID1BAND,
EQUALIZER_MID2GAIN,
EQUALIZER_MID2FREQ,
EQUALIZER_MID2BAND,
EQUALIZER_HIGHGAIN,
EQUALIZER_HIGHCUT,
EFFECT_MAX_ENUM
};
enum ParameterType
{
PAR_FLOAT,
PAR_BOOL,
PAR_WAVEFORM,
PAR_DIRECTION,
PAR_PHONEME,
PAR_MAX_ENUM
PARAM_TYPE,
PARAM_FLOAT,
PARAM_BOOL,
PARAM_WAVEFORM,
//PARAM_DIRECTION,
//PARAM_PHONEME,
PARAM_MAX_ENUM
};
enum Waveform
@@ -69,7 +197,7 @@ public:
WAVE_SQUARE,
WAVE_MAX_ENUM
};
/*
enum Direction
{
DIR_NONE,
@@ -112,6 +240,7 @@ public:
PHONEME_Z,
PHONEME_MAX_ENUM
};
*/
Effect();
virtual ~Effect();
@@ -121,11 +250,13 @@ public:
static bool getConstant(Type in, const char *&out);
static bool getConstant(const char *in, Waveform &out);
static bool getConstant(Waveform in, const char *&out);
static bool getConstant(const char *in, Direction &out);
static bool getConstant(Direction in, const char *&out);
static bool getConstant(const char *in, Phoneme &out);
static bool getConstant(Phoneme in, const char *&out);
static const std::vector<ParameterType> &getParameterTypes(Type in);
//static bool getConstant(const char *in, Direction &out);
//static bool getConstant(Direction in, const char *&out);
//static bool getConstant(const char *in, Phoneme &out);
//static bool getConstant(Phoneme in, const char *&out);
static bool getConstant(const char *in, Parameter &out, Type t);
static bool getConstant(Parameter in, const char *&out, Type t);
static ParameterType getParameterType(Parameter in);
protected:
Type type;
@@ -135,11 +266,28 @@ private:
static StringMap<Type, TYPE_MAX_ENUM> types;
static StringMap<Waveform, WAVE_MAX_ENUM>::Entry waveformEntries[];
static StringMap<Waveform, WAVE_MAX_ENUM> waveforms;
static StringMap<Direction, DIR_MAX_ENUM>::Entry directionEntries[];
static StringMap<Direction, DIR_MAX_ENUM> directions;
static StringMap<Phoneme, PHONEME_MAX_ENUM>::Entry phonemeEntries[];
static StringMap<Phoneme, PHONEME_MAX_ENUM> phonemes;
static std::map<Type, std::vector<Effect::ParameterType>> parameterTypes;
//static StringMap<Direction, DIR_MAX_ENUM>::Entry directionEntries[];
//static StringMap<Direction, DIR_MAX_ENUM> directions;
//static StringMap<Phoneme, PHONEME_MAX_ENUM>::Entry phonemeEntries[];
//static StringMap<Phoneme, PHONEME_MAX_ENUM> phonemes;
#define StringMap LazierAndSlowerButEasilyArrayableStringMap
static std::vector<StringMap<Effect::Parameter>::Entry> basicParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> reverbParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> chorusParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> distortionParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> echoParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> flangerParameters;
//static std::vector<StringMap<Effect::Parameter>::Entry> freqshifterParameters;
//static std::vector<StringMap<Effect::Parameter>::Entry> morpherParameters;
//static std::vector<StringMap<Effect::Parameter>::Entry> pitchshifterParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> modulatorParameters;
//static std::vector<StringMap<Effect::Parameter>::Entry> autowahParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> compressorParameters;
static std::vector<StringMap<Effect::Parameter>::Entry> equalizerParameters;
static std::map<Type, StringMap<Parameter>> parameterNames;
#undef StringMap
static std::map<Parameter, ParameterType> parameterTypes;
};
} //audio
+2 -2
View File
@@ -168,7 +168,7 @@ void Audio::setDistanceModel(DistanceModel distanceModel)
this->distanceModel = distanceModel;
}
bool Audio::setSceneEffect(int, Effect::Type, std::vector<float> &)
bool Audio::setSceneEffect(int, std::map<Effect::Parameter, float> &)
{
return false;
}
@@ -178,7 +178,7 @@ bool Audio::setSceneEffect(int)
return false;
}
bool Audio::getSceneEffect(int, Effect::Type &, std::vector<float> &)
bool Audio::getSceneEffect(int, std::map<Effect::Parameter, float> &)
{
return false;
}
+2 -2
View File
@@ -78,9 +78,9 @@ public:
DistanceModel getDistanceModel() const;
void setDistanceModel(DistanceModel distanceModel);
bool setSceneEffect(int slot, Effect::Type type, std::vector<float> &params);
bool setSceneEffect(int slot, std::map<Effect::Parameter, float> &params);
bool setSceneEffect(int slot);
bool getSceneEffect(int slot, Effect::Type &type, std::vector<float> &params);
bool getSceneEffect(int slot, std::map<Effect::Parameter, float> &params);
int getMaxSceneEffects() const;
int getMaxSourceEffects() const;
bool isEFXsupported() const;
+5 -5
View File
@@ -445,7 +445,7 @@ const std::vector<love::audio::RecordingDevice*> &Audio::getRecordingDevices()
return capture;
}
bool Audio::setSceneEffect(int slot, Effect::Type type, std::vector<float> &params)
bool Audio::setSceneEffect(int slot, std::map<Effect::Parameter, float> &params)
{
if (slot < 0 || slot >= MAX_SCENE_EFFECTS)
return false;
@@ -453,15 +453,16 @@ bool Audio::setSceneEffect(int slot, Effect::Type type, std::vector<float> &para
if (!effects[slot])
effects[slot] = new Effect();
bool result = effects[slot]->setParams(type, params);
bool result = effects[slot]->setParams(params);
#ifdef ALC_EXT_EFX
if (alAuxiliaryEffectSloti)
{
if (result == true)
{
if (params.find(Effect::EFFECT_VOLUME) != params.end())
alAuxiliaryEffectSlotf(effectSlots[slot], AL_EFFECTSLOT_GAIN, params[Effect::EFFECT_VOLUME]);
alAuxiliaryEffectSloti(effectSlots[slot], AL_EFFECTSLOT_EFFECT, effects[slot]->getEffect());
alAuxiliaryEffectSlotf(effectSlots[slot], AL_EFFECTSLOT_GAIN, params[0]);
}
else
alAuxiliaryEffectSloti(effectSlots[slot], AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
@@ -490,7 +491,7 @@ bool Audio::setSceneEffect(int slot)
return true;
}
bool Audio::getSceneEffect(int slot, Effect::Type &type, std::vector<float> &params)
bool Audio::getSceneEffect(int slot, std::map<Effect::Parameter, float> &params)
{
if (slot < 0 || slot >= MAX_SCENE_EFFECTS)
return false;
@@ -498,7 +499,6 @@ bool Audio::getSceneEffect(int slot, Effect::Type &type, std::vector<float> &par
if (!effects[slot])
return false;
type = effects[slot]->getType();
params = effects[slot]->getParams();
return true;
+2 -2
View File
@@ -114,9 +114,9 @@ public:
DistanceModel getDistanceModel() const;
void setDistanceModel(DistanceModel distanceModel);
bool setSceneEffect(int slot, Effect::Type type, std::vector<float> &params);
bool setSceneEffect(int slot, std::map<Effect::Parameter, float> &params);
bool setSceneEffect(int slot);
bool getSceneEffect(int slot, Effect::Type &type, std::vector<float> &params);
bool getSceneEffect(int slot, std::map<Effect::Parameter, float> &params);
int getMaxSceneEffects() const;
int getMaxSourceEffects() const;
bool isEFXsupported() const;
+131 -121
View File
@@ -40,7 +40,7 @@ Effect::Effect()
Effect::Effect(const Effect &s)
: Effect()
{
setParams(s.getType(), s.getParams());
setParams(s.getParams());
}
Effect::~Effect()
@@ -81,21 +81,21 @@ void Effect::deleteEffect()
effect = AL_EFFECT_NULL;
}
ALuint Effect::getEffect() const
{
return effect;
}
bool Effect::setParams(Type type, const std::vector<float> &params)
bool Effect::setParams(const std::map<Parameter, float> &params)
{
this->type = type;
this->params = params;
type = static_cast<Type>(this->params[EFFECT_TYPE]);
if (!generateEffect())
return false;
#ifdef ALC_EXT_EFX
//parameter table without EFFECT_TYPE entry is illegal
switch (type)
{
case TYPE_REVERB:
@@ -113,6 +113,7 @@ bool Effect::setParams(Type type, const std::vector<float> &params)
case TYPE_FLANGER:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER);
break;
/*
case TYPE_FREQSHIFTER:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER);
break;
@@ -122,18 +123,22 @@ bool Effect::setParams(Type type, const std::vector<float> &params)
case TYPE_PITCHSHIFTER:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
break;
*/
case TYPE_MODULATOR:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR);
break;
/*
case TYPE_AUTOWAH:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH);
break;
*/
case TYPE_COMPRESSOR:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR);
break;
case TYPE_EQUALIZER:
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER);
break;
case TYPE_BASIC:
case TYPE_MAX_ENUM:
break;
}
@@ -145,96 +150,98 @@ bool Effect::setParams(Type type, const std::vector<float> &params)
return false;
}
#define PARAMSTR(i,e,v) effect, AL_ ## e ## _ ## v, clampf(params[(i)], AL_ ## e ## _MIN_ ## v, AL_ ## e ## _MAX_ ## v, AL_ ## e ## _DEFAULT_ ## v)
#define clampf(v,l,h) fmax(fmin((v),(h)),(l))
#define PARAMSTR(i,e,v) effect,AL_##e##_##v,clampf(getValue(i,AL_##e##_DEFAULT_##v),AL_##e##_MIN_##v,AL_##e##_MAX_##v)
switch (type)
{
case TYPE_REVERB:
{
alEffectf(PARAMSTR(1,REVERB,GAIN));
alEffectf(PARAMSTR(2,REVERB,GAINHF));
alEffectf(PARAMSTR(3,REVERB,DENSITY));
alEffectf(PARAMSTR(4,REVERB,DIFFUSION));
alEffectf(PARAMSTR(5,REVERB,DECAY_TIME));
alEffectf(PARAMSTR(6,REVERB,DECAY_HFRATIO));
alEffectf(PARAMSTR(7,REVERB,REFLECTIONS_GAIN));
alEffectf(PARAMSTR(8,REVERB,REFLECTIONS_DELAY));
alEffectf(PARAMSTR(9,REVERB,LATE_REVERB_GAIN));
alEffectf(PARAMSTR(10,REVERB,LATE_REVERB_DELAY));;
alEffectf(PARAMSTR(11,REVERB,ROOM_ROLLOFF_FACTOR));
alEffectf(PARAMSTR(12,REVERB,AIR_ABSORPTION_GAINHF));
alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, params[13] < 0.5 ? AL_FALSE : AL_TRUE);
alEffectf(PARAMSTR(REVERB_GAIN,REVERB,GAIN));
alEffectf(PARAMSTR(REVERB_HFGAIN,REVERB,GAINHF));
alEffectf(PARAMSTR(REVERB_DENSITY,REVERB,DENSITY));
alEffectf(PARAMSTR(REVERB_DIFFUSION,REVERB,DIFFUSION));
alEffectf(PARAMSTR(REVERB_DECAY,REVERB,DECAY_TIME));
alEffectf(PARAMSTR(REVERB_HFDECAY,REVERB,DECAY_HFRATIO));
alEffectf(PARAMSTR(REVERB_EARLYGAIN,REVERB,REFLECTIONS_GAIN));
alEffectf(PARAMSTR(REVERB_EARLYDELAY,REVERB,REFLECTIONS_DELAY));
alEffectf(PARAMSTR(REVERB_LATEGAIN,REVERB,LATE_REVERB_GAIN));
alEffectf(PARAMSTR(REVERB_LATEDELAY,REVERB,LATE_REVERB_DELAY));;
alEffectf(PARAMSTR(REVERB_ROLLOFF,REVERB,ROOM_ROLLOFF_FACTOR));
alEffectf(PARAMSTR(REVERB_AIRHFGAIN,REVERB,AIR_ABSORPTION_GAINHF));
alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, getValue(REVERB_HFLIMITER, 0));
break;
}
case TYPE_CHORUS:
{
Effect::Waveform wave = static_cast<Effect::Waveform>(params[1]);
if (wave == Effect::WAVE_SINE)
Waveform wave = static_cast<Waveform>(getValue(CHORUS_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM)));
if (wave == WAVE_SINE)
alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_SINUSOID);
else if (wave == Effect::WAVE_TRIANGLE)
else if (wave == WAVE_TRIANGLE)
alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_TRIANGLE);
else
alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_DEFAULT_WAVEFORM);
alEffecti(PARAMSTR(2,CHORUS,PHASE));
alEffectf(PARAMSTR(3,CHORUS,RATE));
alEffectf(PARAMSTR(4,CHORUS,DEPTH));
alEffectf(PARAMSTR(5,CHORUS,FEEDBACK));
alEffectf(PARAMSTR(6,CHORUS,DELAY));
alEffecti(PARAMSTR(CHORUS_PHASE,CHORUS,PHASE));
alEffectf(PARAMSTR(CHORUS_RATE,CHORUS,RATE));
alEffectf(PARAMSTR(CHORUS_DEPTH,CHORUS,DEPTH));
alEffectf(PARAMSTR(CHORUS_FEEDBACK,CHORUS,FEEDBACK));
alEffectf(PARAMSTR(CHORUS_DELAY,CHORUS,DELAY));
break;
}
case TYPE_DISTORTION:
alEffectf(PARAMSTR(1,DISTORTION,GAIN));
alEffectf(PARAMSTR(2,DISTORTION,EDGE));
alEffectf(PARAMSTR(3,DISTORTION,LOWPASS_CUTOFF));
alEffectf(PARAMSTR(4,DISTORTION,EQCENTER));
alEffectf(PARAMSTR(5,DISTORTION,EQBANDWIDTH));
alEffectf(PARAMSTR(DISTORTION_GAIN,DISTORTION,GAIN));
alEffectf(PARAMSTR(DISTORTION_EDGE,DISTORTION,EDGE));
alEffectf(PARAMSTR(DISTORTION_LOWCUT,DISTORTION,LOWPASS_CUTOFF));
alEffectf(PARAMSTR(DISTORTION_EQCENTER,DISTORTION,EQCENTER));
alEffectf(PARAMSTR(DISTORTION_EQBAND,DISTORTION,EQBANDWIDTH));
break;
case TYPE_ECHO:
alEffectf(PARAMSTR(1,ECHO,DELAY));
alEffectf(PARAMSTR(2,ECHO,LRDELAY));
alEffectf(PARAMSTR(3,ECHO,DAMPING));
alEffectf(PARAMSTR(4,ECHO,FEEDBACK));
alEffectf(PARAMSTR(5,ECHO,SPREAD));
alEffectf(PARAMSTR(ECHO_DELAY,ECHO,DELAY));
alEffectf(PARAMSTR(ECHO_LRDELAY,ECHO,LRDELAY));
alEffectf(PARAMSTR(ECHO_DAMPING,ECHO,DAMPING));
alEffectf(PARAMSTR(ECHO_FEEDBACK,ECHO,FEEDBACK));
alEffectf(PARAMSTR(ECHO_SPREAD,ECHO,SPREAD));
break;
case TYPE_FLANGER:
{
Effect::Waveform wave = static_cast<Effect::Waveform>(params[1]);
if (wave == Effect::WAVE_SINE)
Waveform wave = static_cast<Waveform>(getValue(FLANGER_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM)));
if (wave == WAVE_SINE)
alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_SINUSOID);
else if (wave == Effect::WAVE_TRIANGLE)
else if (wave == WAVE_TRIANGLE)
alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_TRIANGLE);
else
alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_DEFAULT_WAVEFORM);
alEffecti(PARAMSTR(2,FLANGER,PHASE));
alEffectf(PARAMSTR(3,FLANGER,RATE));
alEffectf(PARAMSTR(4,FLANGER,DEPTH));
alEffectf(PARAMSTR(5,FLANGER,FEEDBACK));
alEffectf(PARAMSTR(6,FLANGER,DELAY));
alEffecti(PARAMSTR(FLANGER_PHASE,FLANGER,PHASE));
alEffectf(PARAMSTR(FLANGER_RATE,FLANGER,RATE));
alEffectf(PARAMSTR(FLANGER_DEPTH,FLANGER,DEPTH));
alEffectf(PARAMSTR(FLANGER_FEEDBACK,FLANGER,FEEDBACK));
alEffectf(PARAMSTR(FLANGER_DELAY,FLANGER,DELAY));
break;
}
/*
case TYPE_FREQSHIFTER:
{
alEffectf(PARAMSTR(1,FREQUENCY_SHIFTER,FREQUENCY));
alEffectf(PARAMSTR(FREQSHIFTER_FREQ,FREQUENCY_SHIFTER,FREQUENCY));
Effect::Direction dir = static_cast<Effect::Direction>(params[2]);
if (dir == Effect::DIR_NONE)
Direction dir = static_cast<Direction>(getValue(FREQSHIFTER_LEFTDIR, static_cast<int>(DIR_MAX_ENUM)));
if (dir == DIR_NONE)
alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF);
else if(dir == Effect::DIR_UP)
else if(dir == DIR_UP)
alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP);
else if(dir == Effect::DIR_DOWN)
else if(dir == DIR_DOWN)
alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN);
else
alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION);
dir = static_cast<Effect::Direction>(params[3]);
if (dir == Effect::DIR_NONE)
dir = static_cast<Direction>(getValue(FREQSHIFTER_RIGHTDIR, static_cast<int>(DIR_MAX_ENUM)));
if (dir == DIR_NONE)
alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF);
else if(dir == Effect::DIR_UP)
else if(dir == DIR_UP)
alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP);
else if(dir == Effect::DIR_DOWN)
else if(dir == DIR_DOWN)
alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN);
else
alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION);
@@ -242,110 +249,110 @@ bool Effect::setParams(Type type, const std::vector<float> &params)
}
case TYPE_MORPHER:
{
Effect::Waveform wave = static_cast<Effect::Waveform>(params[1]);
if (wave == Effect::WAVE_SINE)
Waveform wave = static_cast<Waveform>(getValue(MORPHER_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM)));
if (wave == WAVE_SINE)
alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SINUSOID);
else if (wave == Effect::WAVE_TRIANGLE)
else if (wave == WAVE_TRIANGLE)
alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE);
else if (wave == Effect::WAVE_SAWTOOTH)
else if (wave == WAVE_SAWTOOTH)
alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH);
else
alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_DEFAULT_WAVEFORM);
alEffectf(PARAMSTR(2,VOCAL_MORPHER,RATE));
if (isnanf(params[3]))
Phoneme phoneme = static_cast<Phoneme>(getValue(MORPHER_PHONEMEA, static_cast<int>(PHONEME_MAX_ENUM)));
if (phoneme == PHONEME_MAX_ENUM)
alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, AL_VOCAL_MORPHER_DEFAULT_PHONEMEA);
else
alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, phonemeMap[static_cast<Effect::Phoneme>(params[2])]);
alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, phonemeMap[phoneme]);
if (isnanf(params[4]))
phoneme = static_cast<Phoneme>(getValue(MORPHER_PHONEMEB, static_cast<int>(PHONEME_MAX_ENUM)));
if (phoneme == PHONEME_MAX_ENUM)
alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, AL_VOCAL_MORPHER_DEFAULT_PHONEMEB);
else
alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, phonemeMap[static_cast<Effect::Phoneme>(params[3])]);
alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, phonemeMap[phoneme]);
alEffecti(PARAMSTR(5,VOCAL_MORPHER,PHONEMEA_COARSE_TUNING));
alEffecti(PARAMSTR(6,VOCAL_MORPHER,PHONEMEB_COARSE_TUNING));
alEffectf(PARAMSTR(MORPHER_RATE,VOCAL_MORPHER,RATE));
alEffecti(PARAMSTR(MORPHER_TUNEA,VOCAL_MORPHER,PHONEMEA_COARSE_TUNING));
alEffecti(PARAMSTR(MORPHER_TUNEB,VOCAL_MORPHER,PHONEMEB_COARSE_TUNING));
break;
}
case TYPE_PITCHSHIFTER:
{
int coarse = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
int fine = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
if (!isnanf(params[1]))
float tune = getValue(PITCHSHIFTER_PITCH, (float)AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE + (float)(AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE - 50) / 100.0 );
int coarse = (int)floor(tune);
int fine = (int)(fmod(tune, 1.0)*100.0);
if (fine > 50)
{
coarse = (int)floor(params[1]);
fine = (int)(fmod(params[1], 1.0)*100.0);
if (fine > 50)
{
fine -= 100;
coarse += 1;
}
else if (fine < -50)
{
fine += 100;
coarse -= 1;
}
if (coarse > AL_PITCH_SHIFTER_MAX_COARSE_TUNE)
{
coarse = AL_PITCH_SHIFTER_MAX_COARSE_TUNE;
fine = AL_PITCH_SHIFTER_MAX_FINE_TUNE;
}
else if (coarse < AL_PITCH_SHIFTER_MIN_COARSE_TUNE)
{
coarse = AL_PITCH_SHIFTER_MIN_COARSE_TUNE;
fine = AL_PITCH_SHIFTER_MIN_FINE_TUNE;
}
fine -= 100;
coarse += 1;
}
else if (fine < -50)
{
fine += 100;
coarse -= 1;
}
if (coarse > AL_PITCH_SHIFTER_MAX_COARSE_TUNE)
{
coarse = AL_PITCH_SHIFTER_MAX_COARSE_TUNE;
fine = AL_PITCH_SHIFTER_MAX_FINE_TUNE;
}
else if (coarse < AL_PITCH_SHIFTER_MIN_COARSE_TUNE)
{
coarse = AL_PITCH_SHIFTER_MIN_COARSE_TUNE;
fine = AL_PITCH_SHIFTER_MIN_FINE_TUNE;
}
alEffecti(effect, AL_PITCH_SHIFTER_COARSE_TUNE, coarse);
alEffecti(effect, AL_PITCH_SHIFTER_FINE_TUNE, fine);
break;
}
*/
case TYPE_MODULATOR:
{
Effect::Waveform wave = static_cast<Effect::Waveform>(params[1]);
if (wave == Effect::WAVE_SINE)
Waveform wave = static_cast<Waveform>(getValue(MODULATOR_WAVEFORM,static_cast<int>(WAVE_MAX_ENUM)));
if (wave == WAVE_SINE)
alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SINUSOID);
else if (wave == Effect::WAVE_SAWTOOTH)
else if (wave == WAVE_SAWTOOTH)
alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SAWTOOTH);
else if (wave == Effect::WAVE_SQUARE)
else if (wave == WAVE_SQUARE)
alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SQUARE);
else
alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_DEFAULT_WAVEFORM);
alEffectf(PARAMSTR(2,RING_MODULATOR,FREQUENCY));
alEffectf(PARAMSTR(3,RING_MODULATOR,HIGHPASS_CUTOFF));
alEffectf(PARAMSTR(MODULATOR_FREQ,RING_MODULATOR,FREQUENCY));
alEffectf(PARAMSTR(MODULATOR_HIGHCUT,RING_MODULATOR,HIGHPASS_CUTOFF));
break;
}
/*
case TYPE_AUTOWAH:
alEffectf(PARAMSTR(1,AUTOWAH,ATTACK_TIME));
alEffectf(PARAMSTR(2,AUTOWAH,RELEASE_TIME));
alEffectf(PARAMSTR(3,AUTOWAH,RESONANCE));
alEffectf(PARAMSTR(4,AUTOWAH,PEAK_GAIN));
alEffectf(PARAMSTR(AUTOWAH_ATTACK,AUTOWAH,ATTACK_TIME));
alEffectf(PARAMSTR(AUTOWAH_RELEASE,AUTOWAH,RELEASE_TIME));
alEffectf(PARAMSTR(AUTOWAH_RESONANCE,AUTOWAH,RESONANCE));
alEffectf(PARAMSTR(AUTOWAH_PEAKGAIN,AUTOWAH,PEAK_GAIN));
break;
*/
case TYPE_COMPRESSOR:
alEffecti(effect, AL_COMPRESSOR_ONOFF, params[1] < 0.5 ? 0 : 1);
alEffecti(effect, AL_COMPRESSOR_ONOFF, getValue(COMPRESSOR_ENABLE,static_cast<int>(AL_COMPRESSOR_DEFAULT_ONOFF)));
break;
case TYPE_EQUALIZER:
alEffectf(PARAMSTR(1,EQUALIZER,LOW_GAIN));
alEffectf(PARAMSTR(2,EQUALIZER,LOW_CUTOFF));
alEffectf(PARAMSTR(3,EQUALIZER,MID1_GAIN));
alEffectf(PARAMSTR(4,EQUALIZER,MID1_CENTER));
alEffectf(PARAMSTR(5,EQUALIZER,MID1_WIDTH));
alEffectf(PARAMSTR(6,EQUALIZER,MID2_GAIN));
alEffectf(PARAMSTR(7,EQUALIZER,MID2_CENTER));
alEffectf(PARAMSTR(8,EQUALIZER,MID2_WIDTH));
alEffectf(PARAMSTR(9,EQUALIZER,HIGH_GAIN));
alEffectf(PARAMSTR(10,EQUALIZER,HIGH_CUTOFF));
alEffectf(PARAMSTR(EQUALIZER_LOWGAIN,EQUALIZER,LOW_GAIN));
alEffectf(PARAMSTR(EQUALIZER_LOWCUT,EQUALIZER,LOW_CUTOFF));
alEffectf(PARAMSTR(EQUALIZER_MID1GAIN,EQUALIZER,MID1_GAIN));
alEffectf(PARAMSTR(EQUALIZER_MID1FREQ,EQUALIZER,MID1_CENTER));
alEffectf(PARAMSTR(EQUALIZER_MID1BAND,EQUALIZER,MID1_WIDTH));
alEffectf(PARAMSTR(EQUALIZER_MID2GAIN,EQUALIZER,MID2_GAIN));
alEffectf(PARAMSTR(EQUALIZER_MID2FREQ,EQUALIZER,MID2_CENTER));
alEffectf(PARAMSTR(EQUALIZER_MID2BAND,EQUALIZER,MID2_WIDTH));
alEffectf(PARAMSTR(EQUALIZER_HIGHGAIN,EQUALIZER,HIGH_GAIN));
alEffectf(PARAMSTR(EQUALIZER_HIGHCUT,EQUALIZER,HIGH_CUTOFF));
break;
case TYPE_BASIC:
case TYPE_MAX_ENUM:
break;
}
#undef PARAMSTR
#undef clampf
//alGetError();
return true;
@@ -354,20 +361,22 @@ bool Effect::setParams(Type type, const std::vector<float> &params)
#endif //ALC_EXT_EFX
}
const std::vector<float> &Effect::getParams() const
const std::map<Effect::Parameter, float> &Effect::getParams() const
{
return params;
}
//clamp values silently to avoid randomly throwing errors due to implementation differences
float Effect::clampf(float val, float min, float max, float def)
float Effect::getValue(Parameter in, float def) const
{
if (isnanf(val)) return def;
else if (val < min) val = min;
else if (val > max) val = max;
return val;
return params.find(in) == params.end() ? def : params.at(in);
}
int Effect::getValue(Parameter in, int def) const
{
return params.find(in) == params.end() ? def : static_cast<int>(params.at(in));
}
/*
std::map<Effect::Phoneme, ALint> Effect::phonemeMap =
{
{Effect::PHONEME_A, AL_VOCAL_MORPHER_PHONEME_A},
@@ -401,6 +410,7 @@ std::map<Effect::Phoneme, ALint> Effect::phonemeMap =
{Effect::PHONEME_V, AL_VOCAL_MORPHER_PHONEME_V},
{Effect::PHONEME_Z, AL_VOCAL_MORPHER_PHONEME_Z}
};
*/
} //openal
} //audio
+7 -5
View File
@@ -66,16 +66,18 @@ public:
virtual ~Effect();
virtual Effect *clone();
ALuint getEffect() const;
virtual bool setParams(Type type, const std::vector<float> &params);
virtual const std::vector<float> &getParams() const;
virtual bool setParams(const std::map<Parameter, float> &params);
virtual const std::map<Parameter, float> &getParams() const;
private:
bool generateEffect();
void deleteEffect();
float clampf(float val, float min, float max, float def);
float getValue(Parameter in, float def) const;
int getValue(Parameter in, int def) const;
ALuint effect = AL_EFFECT_NULL;
std::vector<float> params;
static std::map<Phoneme, ALint> phonemeMap;
std::map<Parameter, float> params;
//static std::map<Phoneme, ALint> phonemeMap;
};
} //openal
+126 -123
View File
@@ -305,109 +305,107 @@ int w_getRecordingDevices(lua_State *L)
return 1;
}
int setSceneEffectHandleParam(lua_State *L, int pos, Effect::ParameterType type, std::vector<float> &params)
{
if (lua_isnoneornil(L, pos))
params.push_back(nanf(""));
else
{
const char *typestr;
switch (type)
{
case Effect::PAR_FLOAT:
params.push_back(luaL_checknumber(L, pos));
break;
case Effect::PAR_BOOL:
if (!lua_isboolean(L, pos))
return luax_typerror(L, pos, "boolean");
params.push_back(lua_toboolean(L, pos) ? 1.0 : 0.0);
break;
case Effect::PAR_WAVEFORM:
{
typestr = luaL_checkstring(L, pos);
Effect::Waveform waveform;
if (!Effect::getConstant(typestr, waveform))
return luaL_error(L, "Invalid waveform type: %s", typestr);
params.push_back(static_cast<int>(waveform));
break;
}
case Effect::PAR_DIRECTION:
{
typestr = luaL_checkstring(L, pos);
Effect::Direction direction;
if (!Effect::getConstant(typestr, direction))
return luaL_error(L, "Invalid direction type: %s", typestr);
params.push_back(static_cast<int>(direction));
break;
}
case Effect::PAR_PHONEME:
{
typestr = luaL_checkstring(L, pos);
Effect::Phoneme phoneme;
if (!Effect::getConstant(typestr, phoneme))
return luaL_error(L, "Invalid phoneme type: %s", typestr);
params.push_back(static_cast<int>(phoneme));
break;
}
case Effect::PAR_MAX_ENUM:
break;
}
}
return 0;
}
int w_setSceneEffect(lua_State *L)
{
int slot = luaL_checknumber(L, 1) - 1;
const char *typestr;
Effect::Type type;
std::vector<float> params;
if (lua_gettop(L) == 1)
if (lua_gettop(L) == 1 || (lua_gettop(L) == 2 && lua_isnoneornil(L, 2)))
{
lua_pushboolean(L, instance()->setSceneEffect(slot));
return 1;
}
else if (lua_gettop(L) > 2)
luaL_checktype(L, 2, LUA_TTABLE);
const char *paramstr = nullptr;
//find type (mandatory)
Effect::getConstant(Effect::EFFECT_TYPE, paramstr, Effect::TYPE_BASIC);
lua_pushstring(L, paramstr);
lua_rawget(L, 2);
if (lua_type(L, -1) == LUA_TNIL)
return luaL_error(L, "Effect type not specificed.");
Effect::Type type = Effect::TYPE_MAX_ENUM;
const char *typestr = luaL_checkstring(L, -1);
if (!Effect::getConstant(typestr, type))
return luaL_error(L, "Invalid Effect type: %s", typestr);
lua_pop(L, 1);
std::map<Effect::Parameter, float> params;
params[Effect::EFFECT_TYPE] = static_cast<int>(type);
// Iterate over the whole table, reading valid parameters and erroring on invalid ones
lua_pushnil(L);
while (lua_next(L, 2))
{
typestr = luaL_checkstring(L, 2);
if (!Effect::getConstant(typestr, type))
return luaL_error(L, "Invalid effect type: %s", typestr);
const char *keystr = luaL_checkstring(L, -2);
Effect::Parameter param;
params.push_back(luaL_checknumber(L, 3));
const std::vector<Effect::ParameterType> &paramtypes = Effect::getParameterTypes(type);
for (unsigned int i = 0; i < paramtypes.size(); i++)
setSceneEffectHandleParam(L, i + 4, paramtypes[i], params);
}
else if (lua_istable(L, 2))
{
if (lua_objlen(L, 2) == 0) //empty table also clears effect
if(Effect::getConstant(keystr, param, type) || Effect::getConstant(keystr, param, Effect::TYPE_BASIC))
{
lua_pushboolean(L, instance()->setSceneEffect(slot));
return 1;
#define luax_effecterror(l,t) luaL_error(l,"Bad parameter type for %s %s: " t " expected, got %s", typestr, keystr, lua_typename(L, -1))
switch(Effect::getParameterType(param))
{
case Effect::PARAM_FLOAT:
if (!lua_isnumber(L, -1))
return luax_effecterror(L, "number");
params[param] = lua_tonumber(L, -1);
break;
case Effect::PARAM_BOOL:
if (!lua_isboolean(L, -1))
return luax_effecterror(L, "boolean");
params[param] = lua_toboolean(L, -1) ? 1.0 : 0.0;
break;
case Effect::PARAM_WAVEFORM:
{
if (!lua_isstring(L, -1))
return luax_effecterror(L, "string");
paramstr = lua_tostring(L, -1);
Effect::Waveform waveform;
if (!Effect::getConstant(paramstr, waveform))
return luaL_error(L, "Invalid waveform type: %s", paramstr);
params[param] = static_cast<int>(waveform);
break;
}
/*
case Effect::PARAM_DIRECTION:
{
if (!lua_isstring(L, -1))
return luax_effecterror(L, "string");
paramstr = lua_tostring(L, -1);
Effect::Direction direction;
if (!Effect::getConstant(paramstr, direction))
return luaL_error(L, "Invalid direction type: %s", paramstr);
params[param] = static_cast<int>(direction);
break;
}
case Effect::PARAM_PHONEME:
{
if (!lua_isstring(L, -1))
return luax_effecterror(L, "string");
paramstr = lua_tostring(L, -1);
Effect::Phoneme phoneme;
if (!Effect::getConstant(basicstr, phoneme))
return luaL_error(L, "Invalid phoneme type: %s", paramstr);
params[param] = static_cast<int>(phoneme);
break;
}
*/
case Effect::PARAM_TYPE:
case Effect::PARAM_MAX_ENUM:
break;
}
#undef luaL_effecterror
}
lua_rawgeti(L, 2, 1);
typestr = luaL_checkstring(L, -1);
if (!Effect::getConstant(typestr, type))
return luaL_error(L, "Invalid effect type: %s", typestr);
lua_pop(L, 1);
else
luaL_error(L, "Invalid '%s' Effect parameter: %s", typestr, keystr);
const std::vector<Effect::ParameterType> &paramtypes = Effect::getParameterTypes(type);
lua_rawgeti(L, 2, 2);
params.push_back(luaL_checknumber(L, -1));
//remove the value (-1) from stack, keep the key (-2) to feed into lua_next
lua_pop(L, 1);
for (unsigned int i = 0; i < paramtypes.size(); i++)
{
lua_rawgeti(L, 2, i + 3);
setSceneEffectHandleParam(L, -1, paramtypes[i], params);
lua_pop(L, 1);
}
}
else
return luax_typerror(L, 2, "effect description");
luax_catchexcept(L, [&]() { lua_pushboolean(L, instance()->setSceneEffect(slot, type, params)); });
luax_catchexcept(L, [&]() { lua_pushboolean(L, instance()->setSceneEffect(slot, params)); });
return 1;
}
@@ -415,49 +413,54 @@ int w_getSceneEffect(lua_State *L)
{
int slot = luaL_checknumber(L, 1) - 1;
Effect::Type type;
std::vector<float> params;
std::map<Effect::Parameter, float> params;
if (!instance()->getSceneEffect(slot, type, params))
if (!instance()->getSceneEffect(slot, params))
return 0;
const char *str = nullptr;
Effect::getConstant(type, str);
lua_pushstring(L, str);
lua_pushnumber(L, params[0]);
const char *keystr, *valstr;
Effect::Type type = static_cast<Effect::Type>((int)params[Effect::EFFECT_TYPE]);
const std::vector<Effect::ParameterType> &paramtypes = Effect::getParameterTypes(type);
lua_createtable(L, 0, params.size());
for (unsigned int i = 1; i < params.size(); i++)
for (auto p : params)
{
if (isnanf(params[i]))
lua_pushnil(L);
else
switch(paramtypes[i-1])
{
case Effect::PAR_FLOAT:
lua_pushnumber(L, params[i]);
break;
case Effect::PAR_BOOL:
lua_pushboolean(L, params[i] < 0.5 ? false : true);
break;
case Effect::PAR_WAVEFORM:
Effect::getConstant(static_cast<Effect::Waveform>((int)params[i]), str);
lua_pushstring(L, str);
break;
case Effect::PAR_DIRECTION:
Effect::getConstant(static_cast<Effect::Direction>((int)params[i]), str);
lua_pushstring(L, str);
break;
case Effect::PAR_PHONEME:
Effect::getConstant(static_cast<Effect::Phoneme>((int)params[i]), str);
lua_pushstring(L, str);
break;
case Effect::PAR_MAX_ENUM:
break;
}
if (!Effect::getConstant(p.first, keystr, type))
Effect::getConstant(p.first, keystr, Effect::TYPE_BASIC);
lua_pushstring(L, keystr);
switch (Effect::getParameterType(p.first))
{
case Effect::PARAM_FLOAT:
lua_pushnumber(L, p.second);
break;
case Effect::PARAM_BOOL:
lua_pushboolean(L, p.second > 0.5 ? true : false);
break;
case Effect::PARAM_WAVEFORM:
Effect::getConstant(static_cast<Effect::Waveform>((int)p.second), valstr);
lua_pushstring(L, valstr);
break;
/*
case Effect::PARAM_DIRECTION:
Effect::getConstant(static_cast<Effect::Direction>((int)p.second), valstr);
lua_pushstring(L, valstr);
break;
case Effect::PARAM_PHONEME:
Effect::getConstant(static_cast<Effect::Phoneme>((int)p.second), valstr);
lua_pushstring(L, valstr);
break;
*/
case Effect::PARAM_TYPE:
Effect::getConstant(static_cast<Effect::Type>((int)p.second), valstr);
lua_pushstring(L, valstr);
break;
case Effect::PARAM_MAX_ENUM:
break;
}
lua_rawset(L, -3);
}
return params.size() + 1;
return 1;
}
int w_getMaxSceneEffects(lua_State *L)