sound_engine_osc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include "sound_engine_osc.h"
  2. static inline uint16_t sound_engine_pulse(uint32_t acc, uint32_t pw) // 0-FFF pulse width range
  3. {
  4. return (
  5. ((acc >> (((uint32_t)ACC_BITS - 17))) >= ((pw == 0xfff ? pw + 1 : pw) << 4) ?
  6. (WAVE_AMP - 1) :
  7. 0));
  8. }
  9. static inline uint16_t sound_engine_saw(uint32_t acc) {
  10. return (acc >> (ACC_BITS - OUTPUT_BITS - 1)) & (WAVE_AMP - 1);
  11. }
  12. uint16_t sound_engine_triangle(uint32_t acc) {
  13. return (
  14. (((acc & (ACC_LENGTH / 2)) ? ~acc : acc) >> (ACC_BITS - OUTPUT_BITS - 2)) &
  15. (WAVE_AMP * 2 - 1));
  16. }
  17. static inline uint16_t sound_engine_sine(uint32_t acc, SoundEngine* sound_engine) {
  18. return (
  19. (uint16_t)sound_engine->sine_lut[(acc >> (ACC_BITS - SINE_LUT_BITDEPTH))]
  20. << (OUTPUT_BITS - SINE_LUT_BITDEPTH));
  21. }
  22. inline static void shift_lfsr(uint32_t* v, uint32_t tap_0, uint32_t tap_1) {
  23. typedef uint32_t T;
  24. const T zero = (T)(0);
  25. const T lsb = zero + (T)(1);
  26. const T feedback = ((lsb << (tap_0)) ^ (lsb << (tap_1)));
  27. *v = (*v >> 1) ^ ((zero - (*v & lsb)) & feedback);
  28. }
  29. static inline uint16_t sound_engine_noise(SoundEngineChannel* channel, uint32_t prev_acc) {
  30. if((prev_acc & (ACC_LENGTH / 32)) != (channel->accumulator & (ACC_LENGTH / 32))) {
  31. if(channel->waveform & SE_WAVEFORM_NOISE_METAL) {
  32. shift_lfsr(&channel->lfsr, 14, 8);
  33. channel->lfsr &= (1 << (14 + 1)) - 1;
  34. }
  35. else {
  36. shift_lfsr(&channel->lfsr, 22, 17);
  37. channel->lfsr &= (1 << (22 + 1)) - 1;
  38. }
  39. }
  40. return (channel->lfsr) & (WAVE_AMP - 1);
  41. }
  42. uint16_t
  43. sound_engine_osc(SoundEngine* sound_engine, SoundEngineChannel* channel, uint32_t prev_acc) {
  44. switch(channel->waveform) {
  45. case SE_WAVEFORM_NOISE:
  46. case SE_WAVEFORM_NOISE_METAL:
  47. case(SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  48. return sound_engine_noise(channel, prev_acc);
  49. break;
  50. }
  51. case SE_WAVEFORM_PULSE: {
  52. return sound_engine_pulse(channel->accumulator, channel->pw);
  53. break;
  54. }
  55. case SE_WAVEFORM_TRIANGLE: {
  56. return sound_engine_triangle(channel->accumulator);
  57. break;
  58. }
  59. case SE_WAVEFORM_SAW: {
  60. return sound_engine_saw(channel->accumulator);
  61. break;
  62. }
  63. case SE_WAVEFORM_SINE: {
  64. return sound_engine_sine(channel->accumulator, sound_engine);
  65. break;
  66. }
  67. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
  68. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
  69. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  70. return sound_engine_pulse(channel->accumulator, channel->pw) &
  71. sound_engine_noise(channel, prev_acc);
  72. }
  73. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE):
  74. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE_METAL):
  75. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  76. return sound_engine_triangle(channel->accumulator) & sound_engine_noise(channel, prev_acc);
  77. }
  78. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE): {
  79. return sound_engine_pulse(channel->accumulator, channel->pw) &
  80. sound_engine_triangle(channel->accumulator);
  81. }
  82. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
  83. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
  84. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  85. return sound_engine_pulse(channel->accumulator, channel->pw) &
  86. sound_engine_noise(channel, prev_acc) & sound_engine_triangle(channel->accumulator);
  87. }
  88. case(SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  89. case(SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  90. case(SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  91. return sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
  92. }
  93. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW): {
  94. return sound_engine_pulse(channel->accumulator, channel->pw) &
  95. sound_engine_saw(channel->accumulator);
  96. }
  97. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  98. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  99. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  100. return sound_engine_pulse(channel->accumulator, channel->pw) &
  101. sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
  102. }
  103. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW): {
  104. return sound_engine_triangle(channel->accumulator) &
  105. sound_engine_saw(channel->accumulator);
  106. }
  107. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  108. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  109. case(SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  110. return sound_engine_triangle(channel->accumulator) &
  111. sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
  112. }
  113. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW): {
  114. return sound_engine_pulse(channel->accumulator, channel->pw) &
  115. sound_engine_triangle(channel->accumulator) &
  116. sound_engine_saw(channel->accumulator);
  117. }
  118. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  119. case(SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  120. case(
  121. SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE |
  122. SE_WAVEFORM_NOISE_METAL): {
  123. return sound_engine_pulse(channel->accumulator, channel->pw) &
  124. sound_engine_triangle(channel->accumulator) &
  125. sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
  126. }
  127. case(SE_WAVEFORM_SINE | SE_WAVEFORM_NOISE):
  128. case(SE_WAVEFORM_SINE | SE_WAVEFORM_NOISE_METAL):
  129. case(SE_WAVEFORM_SINE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  130. return sound_engine_sine(channel->accumulator, sound_engine) &
  131. sound_engine_noise(channel, prev_acc);
  132. }
  133. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE): {
  134. return sound_engine_pulse(channel->accumulator, channel->pw) &
  135. sound_engine_sine(channel->accumulator, sound_engine);
  136. }
  137. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
  138. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
  139. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  140. return sound_engine_pulse(channel->accumulator, channel->pw) &
  141. sound_engine_sine(channel->accumulator, sound_engine) &
  142. sound_engine_noise(channel, prev_acc);
  143. }
  144. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE): {
  145. return sound_engine_triangle(channel->accumulator) &
  146. sound_engine_sine(channel->accumulator, sound_engine);
  147. }
  148. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE):
  149. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE_METAL):
  150. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  151. return sound_engine_triangle(channel->accumulator) &
  152. sound_engine_sine(channel->accumulator, sound_engine) &
  153. sound_engine_noise(channel, prev_acc);
  154. }
  155. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE): {
  156. return sound_engine_pulse(channel->accumulator, channel->pw) &
  157. sound_engine_triangle(channel->accumulator) &
  158. sound_engine_sine(channel->accumulator, sound_engine);
  159. }
  160. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
  161. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
  162. case(
  163. SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE |
  164. SE_WAVEFORM_NOISE_METAL): {
  165. return sound_engine_pulse(channel->accumulator, channel->pw) &
  166. sound_engine_triangle(channel->accumulator) &
  167. sound_engine_sine(channel->accumulator, sound_engine) &
  168. sound_engine_noise(channel, prev_acc);
  169. }
  170. case(SE_WAVEFORM_SINE | SE_WAVEFORM_SAW): {
  171. return sound_engine_saw(channel->accumulator) &
  172. sound_engine_sine(channel->accumulator, sound_engine);
  173. }
  174. case(SE_WAVEFORM_SINE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  175. case(SE_WAVEFORM_SINE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  176. case(SE_WAVEFORM_SINE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  177. return sound_engine_saw(channel->accumulator) &
  178. sound_engine_sine(channel->accumulator, sound_engine) &
  179. sound_engine_noise(channel, prev_acc);
  180. }
  181. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW): {
  182. return sound_engine_pulse(channel->accumulator, channel->pw) &
  183. sound_engine_saw(channel->accumulator) &
  184. sound_engine_sine(channel->accumulator, sound_engine);
  185. }
  186. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  187. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  188. case(
  189. SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE |
  190. SE_WAVEFORM_NOISE_METAL): {
  191. return sound_engine_pulse(channel->accumulator, channel->pw) &
  192. sound_engine_saw(channel->accumulator) &
  193. sound_engine_sine(channel->accumulator, sound_engine) &
  194. sound_engine_noise(channel, prev_acc);
  195. }
  196. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW): {
  197. return sound_engine_saw(channel->accumulator) &
  198. sound_engine_triangle(channel->accumulator) &
  199. sound_engine_sine(channel->accumulator, sound_engine);
  200. }
  201. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
  202. case(SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
  203. case(
  204. SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE |
  205. SE_WAVEFORM_NOISE_METAL): {
  206. return sound_engine_saw(channel->accumulator) &
  207. sound_engine_triangle(channel->accumulator) &
  208. sound_engine_sine(channel->accumulator, sound_engine) &
  209. sound_engine_noise(channel, prev_acc);
  210. }
  211. case(SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW): {
  212. return sound_engine_saw(channel->accumulator) &
  213. sound_engine_pulse(channel->accumulator, channel->pw) &
  214. sound_engine_triangle(channel->accumulator) &
  215. sound_engine_sine(channel->accumulator, sound_engine);
  216. }
  217. case(
  218. SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW |
  219. SE_WAVEFORM_NOISE):
  220. case(
  221. SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW |
  222. SE_WAVEFORM_NOISE_METAL):
  223. case(
  224. SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW |
  225. SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL): {
  226. return sound_engine_saw(channel->accumulator) &
  227. sound_engine_pulse(channel->accumulator, channel->pw) &
  228. sound_engine_triangle(channel->accumulator) &
  229. sound_engine_sine(channel->accumulator, sound_engine) &
  230. sound_engine_noise(channel, prev_acc);
  231. }
  232. default:
  233. break;
  234. }
  235. return WAVE_AMP / 2;
  236. }