mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
Named Effect parameters added. Unsupported effects disabled.
Unnamed parameter Effect setting is no longer functional. --HG-- branch : minor
This commit is contained in:
@@ -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> ¶ms) = 0;
|
||||
virtual bool setSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms) = 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> ¶ms) = 0;
|
||||
virtual bool getSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms) = 0;
|
||||
|
||||
/**
|
||||
* Gets maximum number of scene EFX effects.
|
||||
|
||||
+235
-35
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@ public:
|
||||
DistanceModel getDistanceModel() const;
|
||||
void setDistanceModel(DistanceModel distanceModel);
|
||||
|
||||
bool setSceneEffect(int slot, Effect::Type type, std::vector<float> ¶ms);
|
||||
bool setSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms);
|
||||
bool setSceneEffect(int slot);
|
||||
bool getSceneEffect(int slot, Effect::Type &type, std::vector<float> ¶ms);
|
||||
bool getSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms);
|
||||
int getMaxSceneEffects() const;
|
||||
int getMaxSourceEffects() const;
|
||||
bool isEFXsupported() const;
|
||||
|
||||
@@ -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> ¶ms)
|
||||
bool Audio::setSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms)
|
||||
{
|
||||
if (slot < 0 || slot >= MAX_SCENE_EFFECTS)
|
||||
return false;
|
||||
@@ -453,15 +453,16 @@ bool Audio::setSceneEffect(int slot, Effect::Type type, std::vector<float> ¶
|
||||
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> ¶ms)
|
||||
bool Audio::getSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -114,9 +114,9 @@ public:
|
||||
DistanceModel getDistanceModel() const;
|
||||
void setDistanceModel(DistanceModel distanceModel);
|
||||
|
||||
bool setSceneEffect(int slot, Effect::Type type, std::vector<float> ¶ms);
|
||||
bool setSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms);
|
||||
bool setSceneEffect(int slot);
|
||||
bool getSceneEffect(int slot, Effect::Type &type, std::vector<float> ¶ms);
|
||||
bool getSceneEffect(int slot, std::map<Effect::Parameter, float> ¶ms);
|
||||
int getMaxSceneEffects() const;
|
||||
int getMaxSourceEffects() const;
|
||||
bool isEFXsupported() const;
|
||||
|
||||
+131
-121
@@ -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> ¶ms)
|
||||
bool Effect::setParams(const std::map<Parameter, float> ¶ms)
|
||||
{
|
||||
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> ¶ms)
|
||||
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> ¶ms)
|
||||
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> ¶ms)
|
||||
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> ¶ms)
|
||||
}
|
||||
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> ¶ms)
|
||||
#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
|
||||
|
||||
@@ -66,16 +66,18 @@ public:
|
||||
virtual ~Effect();
|
||||
virtual Effect *clone();
|
||||
ALuint getEffect() const;
|
||||
virtual bool setParams(Type type, const std::vector<float> ¶ms);
|
||||
virtual const std::vector<float> &getParams() const;
|
||||
virtual bool setParams(const std::map<Parameter, float> ¶ms);
|
||||
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
@@ -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> ¶ms)
|
||||
{
|
||||
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> ¶mtypes = 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> ¶mtypes = 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> ¶mtypes = 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)
|
||||
|
||||
Reference in New Issue
Block a user