1 2 #include "config.h" 3 4 #include "AL/al.h" 5 #include "AL/efx.h" 6 7 #include "aloptional.h" 8 #include "effects.h" 9 #include "effects/base.h" 10 11 12 namespace { 13 14 al::optional<ModulatorWaveform> WaveformFromEmum(ALenum value) 15 { 16 switch(value) 17 { 18 case AL_RING_MODULATOR_SINUSOID: return al::make_optional(ModulatorWaveform::Sinusoid); 19 case AL_RING_MODULATOR_SAWTOOTH: return al::make_optional(ModulatorWaveform::Sawtooth); 20 case AL_RING_MODULATOR_SQUARE: return al::make_optional(ModulatorWaveform::Square); 21 } 22 return al::nullopt; 23 } 24 ALenum EnumFromWaveform(ModulatorWaveform type) 25 { 26 switch(type) 27 { 28 case ModulatorWaveform::Sinusoid: return AL_RING_MODULATOR_SINUSOID; 29 case ModulatorWaveform::Sawtooth: return AL_RING_MODULATOR_SAWTOOTH; 30 case ModulatorWaveform::Square: return AL_RING_MODULATOR_SQUARE; 31 } 32 throw std::runtime_error{"Invalid modulator waveform: " + 33 std::to_string(static_cast<int>(type))}; 34 } 35 36 void Modulator_setParamf(EffectProps *props, ALenum param, float val) 37 { 38 switch(param) 39 { 40 case AL_RING_MODULATOR_FREQUENCY: 41 if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY)) 42 throw effect_exception{AL_INVALID_VALUE, "Modulator frequency out of range: %f", val}; 43 props->Modulator.Frequency = val; 44 break; 45 46 case AL_RING_MODULATOR_HIGHPASS_CUTOFF: 47 if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF)) 48 throw effect_exception{AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: %f", val}; 49 props->Modulator.HighPassCutoff = val; 50 break; 51 52 default: 53 throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param}; 54 } 55 } 56 void Modulator_setParamfv(EffectProps *props, ALenum param, const float *vals) 57 { Modulator_setParamf(props, param, vals[0]); } 58 void Modulator_setParami(EffectProps *props, ALenum param, int val) 59 { 60 switch(param) 61 { 62 case AL_RING_MODULATOR_FREQUENCY: 63 case AL_RING_MODULATOR_HIGHPASS_CUTOFF: 64 Modulator_setParamf(props, param, static_cast<float>(val)); 65 break; 66 67 case AL_RING_MODULATOR_WAVEFORM: 68 if(auto formopt = WaveformFromEmum(val)) 69 props->Modulator.Waveform = *formopt; 70 else 71 throw effect_exception{AL_INVALID_VALUE, "Invalid modulator waveform: 0x%04x", val}; 72 break; 73 74 default: 75 throw effect_exception{AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x", 76 param}; 77 } 78 } 79 void Modulator_setParamiv(EffectProps *props, ALenum param, const int *vals) 80 { Modulator_setParami(props, param, vals[0]); } 81 82 void Modulator_getParami(const EffectProps *props, ALenum param, int *val) 83 { 84 switch(param) 85 { 86 case AL_RING_MODULATOR_FREQUENCY: 87 *val = static_cast<int>(props->Modulator.Frequency); 88 break; 89 case AL_RING_MODULATOR_HIGHPASS_CUTOFF: 90 *val = static_cast<int>(props->Modulator.HighPassCutoff); 91 break; 92 case AL_RING_MODULATOR_WAVEFORM: 93 *val = EnumFromWaveform(props->Modulator.Waveform); 94 break; 95 96 default: 97 throw effect_exception{AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x", 98 param}; 99 } 100 } 101 void Modulator_getParamiv(const EffectProps *props, ALenum param, int *vals) 102 { Modulator_getParami(props, param, vals); } 103 void Modulator_getParamf(const EffectProps *props, ALenum param, float *val) 104 { 105 switch(param) 106 { 107 case AL_RING_MODULATOR_FREQUENCY: 108 *val = props->Modulator.Frequency; 109 break; 110 case AL_RING_MODULATOR_HIGHPASS_CUTOFF: 111 *val = props->Modulator.HighPassCutoff; 112 break; 113 114 default: 115 throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param}; 116 } 117 } 118 void Modulator_getParamfv(const EffectProps *props, ALenum param, float *vals) 119 { Modulator_getParamf(props, param, vals); } 120 121 EffectProps genDefaultProps() noexcept 122 { 123 EffectProps props{}; 124 props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; 125 props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; 126 props.Modulator.Waveform = *WaveformFromEmum(AL_RING_MODULATOR_DEFAULT_WAVEFORM); 127 return props; 128 } 129 130 } // namespace 131 132 DEFINE_ALEFFECT_VTABLE(Modulator); 133 134 const EffectProps ModulatorEffectProps{genDefaultProps()}; 135