do_effects.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "do_effects.h"
  2. #include <furi.h>
  3. #include "../sound_engine/sound_engine_filter.h"
  4. void do_command(uint16_t opcode, TrackerEngine *tracker_engine, uint8_t channel, uint8_t tick, bool from_program)
  5. {
  6. UNUSED(from_program);
  7. TrackerEngineChannel *te_channel = &tracker_engine->channel[channel];
  8. SoundEngineChannel *se_channel = &tracker_engine->sound_engine->channel[channel];
  9. switch (opcode & 0x7f00)
  10. {
  11. case TE_EFFECT_ARPEGGIO:
  12. {
  13. if (tick == 0)
  14. {
  15. if (te_channel->fixed_note != 0xffff)
  16. {
  17. te_channel->note = te_channel->last_note;
  18. te_channel->fixed_note = 0xffff;
  19. }
  20. if ((opcode & 0xff) == 0xf0)
  21. te_channel->arpeggio_note = te_channel->extarp1;
  22. else if ((opcode & 0xff) == 0xf1)
  23. te_channel->arpeggio_note = te_channel->extarp2;
  24. else
  25. te_channel->arpeggio_note = (opcode & 0xff);
  26. }
  27. break;
  28. }
  29. case TE_EFFECT_PORTAMENTO_UP:
  30. {
  31. uint32_t prev = te_channel->note;
  32. te_channel->note += ((opcode & 0xff) << 2);
  33. if (prev > te_channel->note)
  34. te_channel->note = 0xffff;
  35. te_channel->target_note = te_channel->note;
  36. break;
  37. }
  38. case TE_EFFECT_PORTAMENTO_DOWN:
  39. {
  40. int32_t prev = te_channel->note;
  41. te_channel->note -= ((opcode & 0xff) << 2);
  42. if (prev < te_channel->note)
  43. te_channel->note = 0;
  44. te_channel->target_note = te_channel->note;
  45. break;
  46. }
  47. case TE_EFFECT_VIBRATO:
  48. {
  49. if (tick == 0)
  50. {
  51. if (opcode & 0xff)
  52. {
  53. te_channel->flags |= TE_ENABLE_VIBRATO;
  54. te_channel->vibrato_speed = (opcode & 0xf0);
  55. te_channel->vibrato_depth = ((opcode & 0x0f) << 4);
  56. }
  57. else
  58. {
  59. te_channel->flags &= ~(TE_ENABLE_VIBRATO);
  60. }
  61. }
  62. break;
  63. }
  64. case TE_EFFECT_PWM:
  65. {
  66. if (tick == 0)
  67. {
  68. if (opcode & 0xff)
  69. {
  70. te_channel->flags |= TE_ENABLE_PWM;
  71. te_channel->pwm_speed = (opcode & 0xf0);
  72. te_channel->pwm_depth = ((opcode & 0x0f) << 4);
  73. }
  74. else
  75. {
  76. te_channel->flags &= ~(TE_ENABLE_PWM);
  77. }
  78. }
  79. break;
  80. }
  81. case TE_EFFECT_SET_PW:
  82. {
  83. if (tick == 0)
  84. {
  85. te_channel->pw = ((opcode & 0xff) << 4);
  86. }
  87. break;
  88. }
  89. case TE_EFFECT_PW_UP:
  90. {
  91. int16_t temp_pw = te_channel->pw + (int16_t)(opcode & 0xff);
  92. if (temp_pw < 0)
  93. temp_pw = 0;
  94. if (temp_pw > 0xfff)
  95. temp_pw = 0xfff;
  96. te_channel->pw = temp_pw;
  97. break;
  98. }
  99. case TE_EFFECT_PW_DOWN:
  100. {
  101. int16_t temp_pw = te_channel->pw - (int16_t)(opcode & 0xff);
  102. if (temp_pw < 0)
  103. temp_pw = 0;
  104. if (temp_pw > 0xfff)
  105. temp_pw = 0xfff;
  106. te_channel->pw = temp_pw;
  107. break;
  108. }
  109. case TE_EFFECT_SET_CUTOFF:
  110. {
  111. if (tick == 0)
  112. {
  113. te_channel->filter_cutoff = ((opcode & 0xff) << 3);
  114. sound_engine_filter_set_coeff(&se_channel->filter, te_channel->filter_cutoff, te_channel->filter_resonance);
  115. }
  116. break;
  117. }
  118. case TE_EFFECT_VOLUME_FADE:
  119. {
  120. if (!(te_channel->channel_flags & TEC_DISABLED))
  121. {
  122. te_channel->volume -= opcode & 0xf;
  123. if (te_channel->volume > MAX_ADSR_VOLUME)
  124. te_channel->volume = 0;
  125. te_channel->volume += (opcode >> 4) & 0xf;
  126. if (te_channel->volume > MAX_ADSR_VOLUME)
  127. te_channel->volume = MAX_ADSR_VOLUME;
  128. se_channel->adsr.volume = (int32_t)se_channel->adsr.volume * (int32_t)te_channel->volume / MAX_ADSR_VOLUME * (int32_t)te_channel->instrument->adsr.volume / MAX_ADSR_VOLUME;
  129. se_channel->adsr.volume = (int32_t)se_channel->adsr.volume * (int32_t)tracker_engine->master_volume / MAX_ADSR_VOLUME;
  130. }
  131. break;
  132. }
  133. case TE_EFFECT_SET_WAVEFORM:
  134. {
  135. if (tick == 0)
  136. {
  137. se_channel->waveform = (opcode & 0x3f);
  138. }
  139. break;
  140. }
  141. case TE_EFFECT_SET_VOLUME:
  142. {
  143. if (tick == 0)
  144. {
  145. if (!(te_channel->channel_flags & TEC_DISABLED))
  146. {
  147. te_channel->volume = opcode & 0xff;
  148. se_channel->adsr.volume = (int32_t)se_channel->adsr.volume * (int32_t)te_channel->volume / MAX_ADSR_VOLUME * (int32_t)te_channel->instrument->adsr.volume / MAX_ADSR_VOLUME;
  149. se_channel->adsr.volume = (int32_t)se_channel->adsr.volume * (int32_t)tracker_engine->master_volume / MAX_ADSR_VOLUME;
  150. }
  151. }
  152. break;
  153. }
  154. case TE_EFFECT_SET_SPEED_PROG_PERIOD:
  155. {
  156. if (tick == 0)
  157. {
  158. if (from_program)
  159. {
  160. te_channel->program_period = opcode & 0xff;
  161. }
  162. else
  163. {
  164. tracker_engine->song->speed = opcode & 0xff;
  165. }
  166. }
  167. break;
  168. }
  169. default:
  170. break;
  171. }
  172. }