vmorpher.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include "config.h"
  2. #include "AL/al.h"
  3. #include "AL/efx.h"
  4. #include "aloptional.h"
  5. #include "effects.h"
  6. #include "effects/base.h"
  7. namespace {
  8. al::optional<VMorpherPhenome> PhenomeFromEnum(ALenum val)
  9. {
  10. #define HANDLE_PHENOME(x) case AL_VOCAL_MORPHER_PHONEME_ ## x: \
  11. return al::make_optional(VMorpherPhenome::x)
  12. switch(val)
  13. {
  14. HANDLE_PHENOME(A);
  15. HANDLE_PHENOME(E);
  16. HANDLE_PHENOME(I);
  17. HANDLE_PHENOME(O);
  18. HANDLE_PHENOME(U);
  19. HANDLE_PHENOME(AA);
  20. HANDLE_PHENOME(AE);
  21. HANDLE_PHENOME(AH);
  22. HANDLE_PHENOME(AO);
  23. HANDLE_PHENOME(EH);
  24. HANDLE_PHENOME(ER);
  25. HANDLE_PHENOME(IH);
  26. HANDLE_PHENOME(IY);
  27. HANDLE_PHENOME(UH);
  28. HANDLE_PHENOME(UW);
  29. HANDLE_PHENOME(B);
  30. HANDLE_PHENOME(D);
  31. HANDLE_PHENOME(F);
  32. HANDLE_PHENOME(G);
  33. HANDLE_PHENOME(J);
  34. HANDLE_PHENOME(K);
  35. HANDLE_PHENOME(L);
  36. HANDLE_PHENOME(M);
  37. HANDLE_PHENOME(N);
  38. HANDLE_PHENOME(P);
  39. HANDLE_PHENOME(R);
  40. HANDLE_PHENOME(S);
  41. HANDLE_PHENOME(T);
  42. HANDLE_PHENOME(V);
  43. HANDLE_PHENOME(Z);
  44. }
  45. return al::nullopt;
  46. #undef HANDLE_PHENOME
  47. }
  48. ALenum EnumFromPhenome(VMorpherPhenome phenome)
  49. {
  50. #define HANDLE_PHENOME(x) case VMorpherPhenome::x: return AL_VOCAL_MORPHER_PHONEME_ ## x
  51. switch(phenome)
  52. {
  53. HANDLE_PHENOME(A);
  54. HANDLE_PHENOME(E);
  55. HANDLE_PHENOME(I);
  56. HANDLE_PHENOME(O);
  57. HANDLE_PHENOME(U);
  58. HANDLE_PHENOME(AA);
  59. HANDLE_PHENOME(AE);
  60. HANDLE_PHENOME(AH);
  61. HANDLE_PHENOME(AO);
  62. HANDLE_PHENOME(EH);
  63. HANDLE_PHENOME(ER);
  64. HANDLE_PHENOME(IH);
  65. HANDLE_PHENOME(IY);
  66. HANDLE_PHENOME(UH);
  67. HANDLE_PHENOME(UW);
  68. HANDLE_PHENOME(B);
  69. HANDLE_PHENOME(D);
  70. HANDLE_PHENOME(F);
  71. HANDLE_PHENOME(G);
  72. HANDLE_PHENOME(J);
  73. HANDLE_PHENOME(K);
  74. HANDLE_PHENOME(L);
  75. HANDLE_PHENOME(M);
  76. HANDLE_PHENOME(N);
  77. HANDLE_PHENOME(P);
  78. HANDLE_PHENOME(R);
  79. HANDLE_PHENOME(S);
  80. HANDLE_PHENOME(T);
  81. HANDLE_PHENOME(V);
  82. HANDLE_PHENOME(Z);
  83. }
  84. throw std::runtime_error{"Invalid phenome: "+std::to_string(static_cast<int>(phenome))};
  85. #undef HANDLE_PHENOME
  86. }
  87. al::optional<VMorpherWaveform> WaveformFromEmum(ALenum value)
  88. {
  89. switch(value)
  90. {
  91. case AL_VOCAL_MORPHER_WAVEFORM_SINUSOID: return al::make_optional(VMorpherWaveform::Sinusoid);
  92. case AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE: return al::make_optional(VMorpherWaveform::Triangle);
  93. case AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH: return al::make_optional(VMorpherWaveform::Sawtooth);
  94. }
  95. return al::nullopt;
  96. }
  97. ALenum EnumFromWaveform(VMorpherWaveform type)
  98. {
  99. switch(type)
  100. {
  101. case VMorpherWaveform::Sinusoid: return AL_VOCAL_MORPHER_WAVEFORM_SINUSOID;
  102. case VMorpherWaveform::Triangle: return AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE;
  103. case VMorpherWaveform::Sawtooth: return AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH;
  104. }
  105. throw std::runtime_error{"Invalid vocal morpher waveform: " +
  106. std::to_string(static_cast<int>(type))};
  107. }
  108. void Vmorpher_setParami(EffectProps *props, ALenum param, int val)
  109. {
  110. switch(param)
  111. {
  112. case AL_VOCAL_MORPHER_PHONEMEA:
  113. if(auto phenomeopt = PhenomeFromEnum(val))
  114. props->Vmorpher.PhonemeA = *phenomeopt;
  115. else
  116. throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a out of range: 0x%04x", val};
  117. break;
  118. case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING:
  119. if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING))
  120. throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a coarse tuning out of range"};
  121. props->Vmorpher.PhonemeACoarseTuning = val;
  122. break;
  123. case AL_VOCAL_MORPHER_PHONEMEB:
  124. if(auto phenomeopt = PhenomeFromEnum(val))
  125. props->Vmorpher.PhonemeB = *phenomeopt;
  126. else
  127. throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b out of range: 0x%04x", val};
  128. break;
  129. case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING:
  130. if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING))
  131. throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b coarse tuning out of range"};
  132. props->Vmorpher.PhonemeBCoarseTuning = val;
  133. break;
  134. case AL_VOCAL_MORPHER_WAVEFORM:
  135. if(auto formopt = WaveformFromEmum(val))
  136. props->Vmorpher.Waveform = *formopt;
  137. else
  138. throw effect_exception{AL_INVALID_VALUE, "Vocal morpher waveform out of range: 0x%04x", val};
  139. break;
  140. default:
  141. throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer property 0x%04x",
  142. param};
  143. }
  144. }
  145. void Vmorpher_setParamiv(EffectProps*, ALenum param, const int*)
  146. {
  147. throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x",
  148. param};
  149. }
  150. void Vmorpher_setParamf(EffectProps *props, ALenum param, float val)
  151. {
  152. switch(param)
  153. {
  154. case AL_VOCAL_MORPHER_RATE:
  155. if(!(val >= AL_VOCAL_MORPHER_MIN_RATE && val <= AL_VOCAL_MORPHER_MAX_RATE))
  156. throw effect_exception{AL_INVALID_VALUE, "Vocal morpher rate out of range"};
  157. props->Vmorpher.Rate = val;
  158. break;
  159. default:
  160. throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher float property 0x%04x",
  161. param};
  162. }
  163. }
  164. void Vmorpher_setParamfv(EffectProps *props, ALenum param, const float *vals)
  165. { Vmorpher_setParamf(props, param, vals[0]); }
  166. void Vmorpher_getParami(const EffectProps *props, ALenum param, int* val)
  167. {
  168. switch(param)
  169. {
  170. case AL_VOCAL_MORPHER_PHONEMEA:
  171. *val = EnumFromPhenome(props->Vmorpher.PhonemeA);
  172. break;
  173. case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING:
  174. *val = props->Vmorpher.PhonemeACoarseTuning;
  175. break;
  176. case AL_VOCAL_MORPHER_PHONEMEB:
  177. *val = EnumFromPhenome(props->Vmorpher.PhonemeB);
  178. break;
  179. case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING:
  180. *val = props->Vmorpher.PhonemeBCoarseTuning;
  181. break;
  182. case AL_VOCAL_MORPHER_WAVEFORM:
  183. *val = EnumFromWaveform(props->Vmorpher.Waveform);
  184. break;
  185. default:
  186. throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer property 0x%04x",
  187. param};
  188. }
  189. }
  190. void Vmorpher_getParamiv(const EffectProps*, ALenum param, int*)
  191. {
  192. throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x",
  193. param};
  194. }
  195. void Vmorpher_getParamf(const EffectProps *props, ALenum param, float *val)
  196. {
  197. switch(param)
  198. {
  199. case AL_VOCAL_MORPHER_RATE:
  200. *val = props->Vmorpher.Rate;
  201. break;
  202. default:
  203. throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher float property 0x%04x",
  204. param};
  205. }
  206. }
  207. void Vmorpher_getParamfv(const EffectProps *props, ALenum param, float *vals)
  208. { Vmorpher_getParamf(props, param, vals); }
  209. EffectProps genDefaultProps() noexcept
  210. {
  211. EffectProps props{};
  212. props.Vmorpher.Rate = AL_VOCAL_MORPHER_DEFAULT_RATE;
  213. props.Vmorpher.PhonemeA = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEA);
  214. props.Vmorpher.PhonemeB = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEB);
  215. props.Vmorpher.PhonemeACoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING;
  216. props.Vmorpher.PhonemeBCoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING;
  217. props.Vmorpher.Waveform = *WaveformFromEmum(AL_VOCAL_MORPHER_DEFAULT_WAVEFORM);
  218. return props;
  219. }
  220. } // namespace
  221. DEFINE_ALEFFECT_VTABLE(Vmorpher);
  222. const EffectProps VmorpherEffectProps{genDefaultProps()};