| 1 | /** |
| 2 | * Copyright (c) 2006-2023 LOVE Development Team |
| 3 | * |
| 4 | * This software is provided 'as-is', without any express or implied |
| 5 | * warranty. In no event will the authors be held liable for any damages |
| 6 | * arising from the use of this software. |
| 7 | * |
| 8 | * Permission is granted to anyone to use this software for any purpose, |
| 9 | * including commercial applications, and to alter it and redistribute it |
| 10 | * freely, subject to the following restrictions: |
| 11 | * |
| 12 | * 1. The origin of this software must not be misrepresented; you must not |
| 13 | * claim that you wrote the original software. If you use this software |
| 14 | * in a product, an acknowledgment in the product documentation would be |
| 15 | * appreciated but is not required. |
| 16 | * 2. Altered source versions must be plainly marked as such, and must not be |
| 17 | * misrepresented as being the original software. |
| 18 | * 3. This notice may not be removed or altered from any source distribution. |
| 19 | **/ |
| 20 | |
| 21 | #include "Effect.h" |
| 22 | #include "common/Exception.h" |
| 23 | |
| 24 | #include <cmath> |
| 25 | #include <iostream> |
| 26 | |
| 27 | namespace love |
| 28 | { |
| 29 | namespace audio |
| 30 | { |
| 31 | namespace openal |
| 32 | { |
| 33 | |
| 34 | //base class |
| 35 | Effect::Effect() |
| 36 | { |
| 37 | generateEffect(); |
| 38 | } |
| 39 | |
| 40 | Effect::Effect(const Effect &s) |
| 41 | : Effect() |
| 42 | { |
| 43 | setParams(s.getParams()); |
| 44 | } |
| 45 | |
| 46 | Effect::~Effect() |
| 47 | { |
| 48 | deleteEffect(); |
| 49 | } |
| 50 | |
| 51 | Effect *Effect::clone() |
| 52 | { |
| 53 | return new Effect(*this); |
| 54 | } |
| 55 | |
| 56 | bool Effect::generateEffect() |
| 57 | { |
| 58 | #ifdef ALC_EXT_EFX |
| 59 | if (!alGenEffects) |
| 60 | return false; |
| 61 | |
| 62 | if (effect != AL_EFFECT_NULL) |
| 63 | return true; |
| 64 | |
| 65 | alGenEffects(1, &effect); |
| 66 | if (alGetError() != AL_NO_ERROR) |
| 67 | throw love::Exception("Failed to create sound Effect." ); |
| 68 | |
| 69 | return true; |
| 70 | #else |
| 71 | return false; |
| 72 | #endif |
| 73 | } |
| 74 | |
| 75 | void Effect::deleteEffect() |
| 76 | { |
| 77 | #ifdef ALC_EXT_EFX |
| 78 | if (effect != AL_EFFECT_NULL) |
| 79 | alDeleteEffects(1, &effect); |
| 80 | #endif |
| 81 | effect = AL_EFFECT_NULL; |
| 82 | } |
| 83 | |
| 84 | ALuint Effect::getEffect() const |
| 85 | { |
| 86 | return effect; |
| 87 | } |
| 88 | |
| 89 | bool Effect::setParams(const std::map<Parameter, float> ¶ms) |
| 90 | { |
| 91 | this->params = params; |
| 92 | type = (Type)(int) this->params[EFFECT_TYPE]; |
| 93 | |
| 94 | if (!generateEffect()) |
| 95 | return false; |
| 96 | |
| 97 | #ifdef ALC_EXT_EFX |
| 98 | //parameter table without EFFECT_TYPE entry is illegal |
| 99 | switch (type) |
| 100 | { |
| 101 | case TYPE_REVERB: |
| 102 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); |
| 103 | break; |
| 104 | case TYPE_CHORUS: |
| 105 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_CHORUS); |
| 106 | break; |
| 107 | case TYPE_DISTORTION: |
| 108 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION); |
| 109 | break; |
| 110 | case TYPE_ECHO: |
| 111 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO); |
| 112 | break; |
| 113 | case TYPE_FLANGER: |
| 114 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER); |
| 115 | break; |
| 116 | /* |
| 117 | case TYPE_FREQSHIFTER: |
| 118 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER); |
| 119 | break; |
| 120 | case TYPE_MORPHER: |
| 121 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER); |
| 122 | break; |
| 123 | case TYPE_PITCHSHIFTER: |
| 124 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER); |
| 125 | break; |
| 126 | */ |
| 127 | case TYPE_MODULATOR: |
| 128 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR); |
| 129 | break; |
| 130 | /* |
| 131 | case TYPE_AUTOWAH: |
| 132 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH); |
| 133 | break; |
| 134 | */ |
| 135 | case TYPE_COMPRESSOR: |
| 136 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR); |
| 137 | break; |
| 138 | case TYPE_EQUALIZER: |
| 139 | alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER); |
| 140 | break; |
| 141 | case TYPE_BASIC: |
| 142 | case TYPE_MAX_ENUM: |
| 143 | break; |
| 144 | } |
| 145 | |
| 146 | //failed to make effect specific type - not supported etc. |
| 147 | if (alGetError() != AL_NO_ERROR) |
| 148 | { |
| 149 | deleteEffect(); |
| 150 | return false; |
| 151 | } |
| 152 | |
| 153 | #define clampf(v,l,h) fmax(fmin((v),(h)),(l)) |
| 154 | #define PARAMSTR(i,e,v) effect,AL_##e##_##v,clampf(getValue(i,AL_##e##_DEFAULT_##v),AL_##e##_MIN_##v,AL_##e##_MAX_##v) |
| 155 | switch (type) |
| 156 | { |
| 157 | case TYPE_REVERB: |
| 158 | { |
| 159 | alEffectf(PARAMSTR(REVERB_GAIN,REVERB,GAIN)); |
| 160 | alEffectf(PARAMSTR(REVERB_HFGAIN,REVERB,GAINHF)); |
| 161 | alEffectf(PARAMSTR(REVERB_DENSITY,REVERB,DENSITY)); |
| 162 | alEffectf(PARAMSTR(REVERB_DIFFUSION,REVERB,DIFFUSION)); |
| 163 | alEffectf(PARAMSTR(REVERB_DECAY,REVERB,DECAY_TIME)); |
| 164 | alEffectf(PARAMSTR(REVERB_HFDECAY,REVERB,DECAY_HFRATIO)); |
| 165 | alEffectf(PARAMSTR(REVERB_EARLYGAIN,REVERB,REFLECTIONS_GAIN)); |
| 166 | alEffectf(PARAMSTR(REVERB_EARLYDELAY,REVERB,REFLECTIONS_DELAY)); |
| 167 | alEffectf(PARAMSTR(REVERB_LATEGAIN,REVERB,LATE_REVERB_GAIN)); |
| 168 | alEffectf(PARAMSTR(REVERB_LATEDELAY,REVERB,LATE_REVERB_DELAY));; |
| 169 | alEffectf(PARAMSTR(REVERB_ROLLOFF,REVERB,ROOM_ROLLOFF_FACTOR)); |
| 170 | alEffectf(PARAMSTR(REVERB_AIRHFGAIN,REVERB,AIR_ABSORPTION_GAINHF)); |
| 171 | alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, getValue(REVERB_HFLIMITER, 0)); |
| 172 | break; |
| 173 | } |
| 174 | case TYPE_CHORUS: |
| 175 | { |
| 176 | Waveform wave = static_cast<Waveform>(getValue(CHORUS_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM))); |
| 177 | if (wave == WAVE_SINE) |
| 178 | alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_SINUSOID); |
| 179 | else if (wave == WAVE_TRIANGLE) |
| 180 | alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_TRIANGLE); |
| 181 | else |
| 182 | alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_DEFAULT_WAVEFORM); |
| 183 | |
| 184 | alEffecti(PARAMSTR(CHORUS_PHASE,CHORUS,PHASE)); |
| 185 | alEffectf(PARAMSTR(CHORUS_RATE,CHORUS,RATE)); |
| 186 | alEffectf(PARAMSTR(CHORUS_DEPTH,CHORUS,DEPTH)); |
| 187 | alEffectf(PARAMSTR(CHORUS_FEEDBACK,CHORUS,FEEDBACK)); |
| 188 | alEffectf(PARAMSTR(CHORUS_DELAY,CHORUS,DELAY)); |
| 189 | break; |
| 190 | } |
| 191 | case TYPE_DISTORTION: |
| 192 | alEffectf(PARAMSTR(DISTORTION_GAIN,DISTORTION,GAIN)); |
| 193 | alEffectf(PARAMSTR(DISTORTION_EDGE,DISTORTION,EDGE)); |
| 194 | alEffectf(PARAMSTR(DISTORTION_LOWCUT,DISTORTION,LOWPASS_CUTOFF)); |
| 195 | alEffectf(PARAMSTR(DISTORTION_EQCENTER,DISTORTION,EQCENTER)); |
| 196 | alEffectf(PARAMSTR(DISTORTION_EQBAND,DISTORTION,EQBANDWIDTH)); |
| 197 | break; |
| 198 | |
| 199 | case TYPE_ECHO: |
| 200 | alEffectf(PARAMSTR(ECHO_DELAY,ECHO,DELAY)); |
| 201 | alEffectf(PARAMSTR(ECHO_LRDELAY,ECHO,LRDELAY)); |
| 202 | alEffectf(PARAMSTR(ECHO_DAMPING,ECHO,DAMPING)); |
| 203 | alEffectf(PARAMSTR(ECHO_FEEDBACK,ECHO,FEEDBACK)); |
| 204 | alEffectf(PARAMSTR(ECHO_SPREAD,ECHO,SPREAD)); |
| 205 | break; |
| 206 | |
| 207 | case TYPE_FLANGER: |
| 208 | { |
| 209 | Waveform wave = static_cast<Waveform>(getValue(FLANGER_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM))); |
| 210 | if (wave == WAVE_SINE) |
| 211 | alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_SINUSOID); |
| 212 | else if (wave == WAVE_TRIANGLE) |
| 213 | alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_TRIANGLE); |
| 214 | else |
| 215 | alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_DEFAULT_WAVEFORM); |
| 216 | |
| 217 | alEffecti(PARAMSTR(FLANGER_PHASE,FLANGER,PHASE)); |
| 218 | alEffectf(PARAMSTR(FLANGER_RATE,FLANGER,RATE)); |
| 219 | alEffectf(PARAMSTR(FLANGER_DEPTH,FLANGER,DEPTH)); |
| 220 | alEffectf(PARAMSTR(FLANGER_FEEDBACK,FLANGER,FEEDBACK)); |
| 221 | alEffectf(PARAMSTR(FLANGER_DELAY,FLANGER,DELAY)); |
| 222 | break; |
| 223 | } |
| 224 | /* |
| 225 | case TYPE_FREQSHIFTER: |
| 226 | { |
| 227 | alEffectf(PARAMSTR(FREQSHIFTER_FREQ,FREQUENCY_SHIFTER,FREQUENCY)); |
| 228 | |
| 229 | Direction dir = static_cast<Direction>(getValue(FREQSHIFTER_LEFTDIR, static_cast<int>(DIR_MAX_ENUM))); |
| 230 | if (dir == DIR_NONE) |
| 231 | alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF); |
| 232 | else if(dir == DIR_UP) |
| 233 | alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP); |
| 234 | else if(dir == DIR_DOWN) |
| 235 | alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN); |
| 236 | else |
| 237 | alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION); |
| 238 | |
| 239 | dir = static_cast<Direction>(getValue(FREQSHIFTER_RIGHTDIR, static_cast<int>(DIR_MAX_ENUM))); |
| 240 | if (dir == DIR_NONE) |
| 241 | alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF); |
| 242 | else if(dir == DIR_UP) |
| 243 | alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP); |
| 244 | else if(dir == DIR_DOWN) |
| 245 | alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN); |
| 246 | else |
| 247 | alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION); |
| 248 | break; |
| 249 | } |
| 250 | case TYPE_MORPHER: |
| 251 | { |
| 252 | Waveform wave = static_cast<Waveform>(getValue(MORPHER_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM))); |
| 253 | if (wave == WAVE_SINE) |
| 254 | alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SINUSOID); |
| 255 | else if (wave == WAVE_TRIANGLE) |
| 256 | alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE); |
| 257 | else if (wave == WAVE_SAWTOOTH) |
| 258 | alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH); |
| 259 | else |
| 260 | alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_DEFAULT_WAVEFORM); |
| 261 | |
| 262 | Phoneme phoneme = static_cast<Phoneme>(getValue(MORPHER_PHONEMEA, static_cast<int>(PHONEME_MAX_ENUM))); |
| 263 | if (phoneme == PHONEME_MAX_ENUM) |
| 264 | alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, AL_VOCAL_MORPHER_DEFAULT_PHONEMEA); |
| 265 | else |
| 266 | alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, phonemeMap[phoneme]); |
| 267 | |
| 268 | phoneme = static_cast<Phoneme>(getValue(MORPHER_PHONEMEB, static_cast<int>(PHONEME_MAX_ENUM))); |
| 269 | if (phoneme == PHONEME_MAX_ENUM) |
| 270 | alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, AL_VOCAL_MORPHER_DEFAULT_PHONEMEB); |
| 271 | else |
| 272 | alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, phonemeMap[phoneme]); |
| 273 | |
| 274 | alEffectf(PARAMSTR(MORPHER_RATE,VOCAL_MORPHER,RATE)); |
| 275 | alEffecti(PARAMSTR(MORPHER_TUNEA,VOCAL_MORPHER,PHONEMEA_COARSE_TUNING)); |
| 276 | alEffecti(PARAMSTR(MORPHER_TUNEB,VOCAL_MORPHER,PHONEMEB_COARSE_TUNING)); |
| 277 | break; |
| 278 | } |
| 279 | case TYPE_PITCHSHIFTER: |
| 280 | { |
| 281 | float tune = getValue(PITCHSHIFTER_PITCH, (float)AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE + (float)(AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE - 50) / 100.0 ); |
| 282 | |
| 283 | int coarse = (int)floor(tune); |
| 284 | int fine = (int)(fmod(tune, 1.0)*100.0); |
| 285 | if (fine > 50) |
| 286 | { |
| 287 | fine -= 100; |
| 288 | coarse += 1; |
| 289 | } |
| 290 | else if (fine < -50) |
| 291 | { |
| 292 | fine += 100; |
| 293 | coarse -= 1; |
| 294 | } |
| 295 | if (coarse > AL_PITCH_SHIFTER_MAX_COARSE_TUNE) |
| 296 | { |
| 297 | coarse = AL_PITCH_SHIFTER_MAX_COARSE_TUNE; |
| 298 | fine = AL_PITCH_SHIFTER_MAX_FINE_TUNE; |
| 299 | } |
| 300 | else if (coarse < AL_PITCH_SHIFTER_MIN_COARSE_TUNE) |
| 301 | { |
| 302 | coarse = AL_PITCH_SHIFTER_MIN_COARSE_TUNE; |
| 303 | fine = AL_PITCH_SHIFTER_MIN_FINE_TUNE; |
| 304 | } |
| 305 | alEffecti(effect, AL_PITCH_SHIFTER_COARSE_TUNE, coarse); |
| 306 | alEffecti(effect, AL_PITCH_SHIFTER_FINE_TUNE, fine); |
| 307 | break; |
| 308 | } |
| 309 | */ |
| 310 | case TYPE_MODULATOR: |
| 311 | { |
| 312 | Waveform wave = static_cast<Waveform>(getValue(MODULATOR_WAVEFORM,static_cast<int>(WAVE_MAX_ENUM))); |
| 313 | if (wave == WAVE_SINE) |
| 314 | alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SINUSOID); |
| 315 | else if (wave == WAVE_SAWTOOTH) |
| 316 | alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SAWTOOTH); |
| 317 | else if (wave == WAVE_SQUARE) |
| 318 | alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SQUARE); |
| 319 | else |
| 320 | alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_DEFAULT_WAVEFORM); |
| 321 | |
| 322 | alEffectf(PARAMSTR(MODULATOR_FREQ,RING_MODULATOR,FREQUENCY)); |
| 323 | alEffectf(PARAMSTR(MODULATOR_HIGHCUT,RING_MODULATOR,HIGHPASS_CUTOFF)); |
| 324 | break; |
| 325 | } |
| 326 | /* |
| 327 | case TYPE_AUTOWAH: |
| 328 | alEffectf(PARAMSTR(AUTOWAH_ATTACK,AUTOWAH,ATTACK_TIME)); |
| 329 | alEffectf(PARAMSTR(AUTOWAH_RELEASE,AUTOWAH,RELEASE_TIME)); |
| 330 | alEffectf(PARAMSTR(AUTOWAH_RESONANCE,AUTOWAH,RESONANCE)); |
| 331 | alEffectf(PARAMSTR(AUTOWAH_PEAKGAIN,AUTOWAH,PEAK_GAIN)); |
| 332 | break; |
| 333 | */ |
| 334 | case TYPE_COMPRESSOR: |
| 335 | alEffecti(effect, AL_COMPRESSOR_ONOFF, getValue(COMPRESSOR_ENABLE,static_cast<int>(AL_COMPRESSOR_DEFAULT_ONOFF))); |
| 336 | break; |
| 337 | |
| 338 | case TYPE_EQUALIZER: |
| 339 | alEffectf(PARAMSTR(EQUALIZER_LOWGAIN,EQUALIZER,LOW_GAIN)); |
| 340 | alEffectf(PARAMSTR(EQUALIZER_LOWCUT,EQUALIZER,LOW_CUTOFF)); |
| 341 | alEffectf(PARAMSTR(EQUALIZER_MID1GAIN,EQUALIZER,MID1_GAIN)); |
| 342 | alEffectf(PARAMSTR(EQUALIZER_MID1FREQ,EQUALIZER,MID1_CENTER)); |
| 343 | alEffectf(PARAMSTR(EQUALIZER_MID1BAND,EQUALIZER,MID1_WIDTH)); |
| 344 | alEffectf(PARAMSTR(EQUALIZER_MID2GAIN,EQUALIZER,MID2_GAIN)); |
| 345 | alEffectf(PARAMSTR(EQUALIZER_MID2FREQ,EQUALIZER,MID2_CENTER)); |
| 346 | alEffectf(PARAMSTR(EQUALIZER_MID2BAND,EQUALIZER,MID2_WIDTH)); |
| 347 | alEffectf(PARAMSTR(EQUALIZER_HIGHGAIN,EQUALIZER,HIGH_GAIN)); |
| 348 | alEffectf(PARAMSTR(EQUALIZER_HIGHCUT,EQUALIZER,HIGH_CUTOFF)); |
| 349 | break; |
| 350 | case TYPE_BASIC: |
| 351 | case TYPE_MAX_ENUM: |
| 352 | break; |
| 353 | } |
| 354 | #undef PARAMSTR |
| 355 | #undef clampf |
| 356 | //alGetError(); |
| 357 | |
| 358 | return true; |
| 359 | #else |
| 360 | return false; |
| 361 | #endif //ALC_EXT_EFX |
| 362 | } |
| 363 | |
| 364 | const std::map<Effect::Parameter, float> &Effect::getParams() const |
| 365 | { |
| 366 | return params; |
| 367 | } |
| 368 | |
| 369 | float Effect::getValue(Parameter in, float def) const |
| 370 | { |
| 371 | return params.find(in) == params.end() ? def : params.at(in); |
| 372 | } |
| 373 | |
| 374 | int Effect::getValue(Parameter in, int def) const |
| 375 | { |
| 376 | return params.find(in) == params.end() ? def : static_cast<int>(params.at(in)); |
| 377 | } |
| 378 | |
| 379 | /* |
| 380 | std::map<Effect::Phoneme, ALint> Effect::phonemeMap = |
| 381 | { |
| 382 | {Effect::PHONEME_A, AL_VOCAL_MORPHER_PHONEME_A}, |
| 383 | {Effect::PHONEME_E, AL_VOCAL_MORPHER_PHONEME_E}, |
| 384 | {Effect::PHONEME_I, AL_VOCAL_MORPHER_PHONEME_I}, |
| 385 | {Effect::PHONEME_O, AL_VOCAL_MORPHER_PHONEME_O}, |
| 386 | {Effect::PHONEME_U, AL_VOCAL_MORPHER_PHONEME_U}, |
| 387 | {Effect::PHONEME_AA, AL_VOCAL_MORPHER_PHONEME_AA}, |
| 388 | {Effect::PHONEME_AE, AL_VOCAL_MORPHER_PHONEME_AE}, |
| 389 | {Effect::PHONEME_AH, AL_VOCAL_MORPHER_PHONEME_AH}, |
| 390 | {Effect::PHONEME_AO, AL_VOCAL_MORPHER_PHONEME_AO}, |
| 391 | {Effect::PHONEME_EH, AL_VOCAL_MORPHER_PHONEME_EH}, |
| 392 | {Effect::PHONEME_ER, AL_VOCAL_MORPHER_PHONEME_ER}, |
| 393 | {Effect::PHONEME_IH, AL_VOCAL_MORPHER_PHONEME_IH}, |
| 394 | {Effect::PHONEME_IY, AL_VOCAL_MORPHER_PHONEME_IY}, |
| 395 | {Effect::PHONEME_UH, AL_VOCAL_MORPHER_PHONEME_UH}, |
| 396 | {Effect::PHONEME_UW, AL_VOCAL_MORPHER_PHONEME_UW}, |
| 397 | {Effect::PHONEME_B, AL_VOCAL_MORPHER_PHONEME_B}, |
| 398 | {Effect::PHONEME_D, AL_VOCAL_MORPHER_PHONEME_D}, |
| 399 | {Effect::PHONEME_F, AL_VOCAL_MORPHER_PHONEME_F}, |
| 400 | {Effect::PHONEME_G, AL_VOCAL_MORPHER_PHONEME_G}, |
| 401 | {Effect::PHONEME_J, AL_VOCAL_MORPHER_PHONEME_J}, |
| 402 | {Effect::PHONEME_K, AL_VOCAL_MORPHER_PHONEME_K}, |
| 403 | {Effect::PHONEME_L, AL_VOCAL_MORPHER_PHONEME_L}, |
| 404 | {Effect::PHONEME_M, AL_VOCAL_MORPHER_PHONEME_M}, |
| 405 | {Effect::PHONEME_N, AL_VOCAL_MORPHER_PHONEME_N}, |
| 406 | {Effect::PHONEME_P, AL_VOCAL_MORPHER_PHONEME_P}, |
| 407 | {Effect::PHONEME_R, AL_VOCAL_MORPHER_PHONEME_R}, |
| 408 | {Effect::PHONEME_S, AL_VOCAL_MORPHER_PHONEME_S}, |
| 409 | {Effect::PHONEME_T, AL_VOCAL_MORPHER_PHONEME_T}, |
| 410 | {Effect::PHONEME_V, AL_VOCAL_MORPHER_PHONEME_V}, |
| 411 | {Effect::PHONEME_Z, AL_VOCAL_MORPHER_PHONEME_Z} |
| 412 | }; |
| 413 | */ |
| 414 | |
| 415 | } //openal |
| 416 | } //audio |
| 417 | } //love |
| 418 | |