cp_player_data_effects.cpp 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. /*************************************************************************/
  2. /* cp_player_data_effects.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "cp_player_data.h"
  31. /**********************
  32. complex effects
  33. ***********************/
  34. #define RANDOM_MAX 2147483647
  35. static inline int32_t cp_random_generate(int32_t *seed) {
  36. int32_t k;
  37. int32_t s = (int32_t)(*seed);
  38. if (s == 0)
  39. s = 0x12345987;
  40. k = s / 127773;
  41. s = 16807 * (s - k * 127773) - 2836 * k;
  42. if (s < 0)
  43. s += 2147483647;
  44. (*seed) = (int32_t)s;
  45. return (int32_t)(s & RANDOM_MAX);
  46. }
  47. void CPPlayer::do_vibrato(int p_track, bool fine) {
  48. uint8_t q;
  49. uint16_t temp = 0;
  50. if ((control.ticks_counter == 0) && control.channel[p_track].row_has_note) control.channel[p_track].vibrato_position = 0;
  51. q = (control.channel[p_track].vibrato_position >> 2) & 0x1f;
  52. switch (control.channel[p_track].vibrato_type) {
  53. case 0: /* sine */
  54. temp = vibrato_table[q];
  55. break;
  56. case 1: /* square wave */
  57. temp = 255;
  58. break;
  59. case 2: /* ramp down */
  60. q <<= 3;
  61. if (control.channel[p_track].vibrato_position < 0) q = 255 - q;
  62. temp = q;
  63. break;
  64. case 3: /* random */
  65. temp = cp_random_generate(&control.random_seed) % 256; //getrandom(256);
  66. break;
  67. }
  68. temp *= control.channel[p_track].vibrato_depth;
  69. if (song->has_old_effects()) {
  70. temp >>= 7;
  71. } else {
  72. temp >>= 8;
  73. }
  74. if (!fine) temp <<= 2;
  75. if (control.channel[p_track].vibrato_position >= 0) {
  76. control.channel[p_track].period = control.channel[p_track].aux_period + temp;
  77. } else {
  78. control.channel[p_track].period = control.channel[p_track].aux_period - temp;
  79. }
  80. if (!song->has_old_effects() || control.ticks_counter) control.channel[p_track].vibrato_position += control.channel[p_track].vibrato_speed;
  81. }
  82. void CPPlayer::do_pitch_slide_down(int p_track, uint8_t inf) {
  83. uint8_t hi, lo;
  84. if (inf)
  85. control.channel[p_track].pitch_slide_info = inf;
  86. else
  87. inf = control.channel[p_track].pitch_slide_info;
  88. hi = inf >> 4;
  89. lo = inf & 0xf;
  90. if (hi == 0xf) {
  91. if (!control.ticks_counter) control.channel[p_track].aux_period += (uint16_t)lo << 2;
  92. } else if (hi == 0xe) {
  93. if (!control.ticks_counter) control.channel[p_track].aux_period += lo;
  94. } else {
  95. if (control.ticks_counter) control.channel[p_track].aux_period += (uint16_t)inf << 2;
  96. }
  97. }
  98. void CPPlayer::do_pitch_slide_up(int p_track, uint8_t inf) {
  99. uint8_t hi, lo;
  100. if (inf)
  101. control.channel[p_track].pitch_slide_info = inf;
  102. else
  103. inf = control.channel[p_track].pitch_slide_info;
  104. hi = inf >> 4;
  105. lo = inf & 0xf;
  106. if (hi == 0xf) {
  107. if (!control.ticks_counter) control.channel[p_track].aux_period -= (uint16_t)lo << 2;
  108. } else if (hi == 0xe) {
  109. if (!control.ticks_counter) control.channel[p_track].aux_period -= lo;
  110. } else {
  111. if (control.ticks_counter) control.channel[p_track].aux_period -= (uint16_t)inf << 2;
  112. }
  113. }
  114. void CPPlayer::do_pitch_slide_to_note(int p_track) {
  115. if (control.ticks_counter) {
  116. int dist;
  117. /* We have to slide a->period towards a->wantedperiod, compute the
  118. difference between those two values */
  119. dist = control.channel[p_track].period - control.channel[p_track].slide_to_period;
  120. /* if they are equal or if portamentospeed is too big... */
  121. if ((!dist) || ((control.channel[p_track].portamento_speed << 2) > cp_intabs(dist))) {
  122. /* ... make tmpperiod equal tperiod */
  123. control.channel[p_track].aux_period = control.channel[p_track].period = control.channel[p_track].slide_to_period;
  124. } else {
  125. if (dist > 0) {
  126. control.channel[p_track].aux_period -= control.channel[p_track].portamento_speed << 2;
  127. control.channel[p_track].period -= control.channel[p_track].portamento_speed << 2; /* dist>0 slide up */
  128. } else {
  129. control.channel[p_track].aux_period += control.channel[p_track].portamento_speed << 2;
  130. control.channel[p_track].period += control.channel[p_track].portamento_speed << 2; /* dist<0 slide down */
  131. }
  132. }
  133. } else {
  134. control.channel[p_track].aux_period = control.channel[p_track].period;
  135. }
  136. }
  137. void CPPlayer::do_tremor(int p_track) {
  138. uint8_t on, off, inf;
  139. inf = control.channel[p_track].current_parameter;
  140. if (inf) {
  141. control.channel[p_track].tremor_info = inf;
  142. } else {
  143. inf = control.channel[p_track].tremor_info;
  144. if (!inf) return;
  145. }
  146. //if (!control.ticks_counter) return;
  147. on = (inf >> 4);
  148. off = (inf & 0xf);
  149. control.channel[p_track].tremor_position %= (on + off);
  150. control.channel[p_track].volume = (control.channel[p_track].tremor_position < on) ? control.channel[p_track].aux_volume : 0;
  151. control.channel[p_track].tremor_position++;
  152. }
  153. void CPPlayer::do_pan_slide(int p_track) {
  154. uint8_t lo, hi, inf;
  155. int16_t pan;
  156. inf = control.channel[p_track].current_parameter;
  157. if (inf)
  158. control.channel[p_track].channel_pan_slide_info = inf;
  159. else
  160. inf = control.channel[p_track].channel_pan_slide_info;
  161. lo = inf & 0xf;
  162. hi = inf >> 4;
  163. pan = (control.channel[p_track].panning == PAN_SURROUND) ? PAN_CENTER : control.channel[p_track].panning;
  164. if (!hi)
  165. pan += lo << 2;
  166. else if (!lo) {
  167. pan -= hi << 2;
  168. } else if (hi == 0xf) {
  169. if (!control.ticks_counter) pan += lo << 2;
  170. } else if (lo == 0xf) {
  171. if (!control.ticks_counter) pan -= hi << 2;
  172. }
  173. //this sets both chan & voice paning
  174. control.channel[p_track].panning = (pan < PAN_LEFT) ? PAN_LEFT : (pan > PAN_RIGHT ? PAN_RIGHT : pan);
  175. control.channel[p_track].channel_panning = control.channel[p_track].panning;
  176. }
  177. void CPPlayer::do_volume_slide(int p_track, int inf) {
  178. uint8_t hi, lo;
  179. lo = inf & 0xf;
  180. hi = inf >> 4;
  181. if (!lo) {
  182. if ((control.ticks_counter)) control.channel[p_track].aux_volume += hi;
  183. } else if (!hi) {
  184. if ((control.ticks_counter)) control.channel[p_track].aux_volume -= lo;
  185. } else if (lo == 0xf) {
  186. if (!control.ticks_counter) control.channel[p_track].aux_volume += (hi ? hi : 0xf);
  187. } else if (hi == 0xf) {
  188. if (!control.ticks_counter) control.channel[p_track].aux_volume -= (lo ? lo : 0xf);
  189. } else
  190. return;
  191. if (control.channel[p_track].aux_volume < 0) {
  192. control.channel[p_track].aux_volume = 0;
  193. } else if (control.channel[p_track].aux_volume > 64) {
  194. control.channel[p_track].aux_volume = 64;
  195. }
  196. }
  197. void CPPlayer::do_channel_volume_slide(int p_track) {
  198. uint8_t lo, hi, inf;
  199. inf = control.channel[p_track].current_parameter;
  200. if (inf) control.channel[p_track].channel_volume_slide_info = inf;
  201. inf = control.channel[p_track].channel_volume_slide_info;
  202. lo = inf & 0xf;
  203. hi = inf >> 4;
  204. if (!hi)
  205. control.channel[p_track].channel_volume -= lo;
  206. else if (!lo) {
  207. control.channel[p_track].channel_volume += hi;
  208. } else if (hi == 0xf) {
  209. if (!control.ticks_counter) control.channel[p_track].channel_volume -= lo;
  210. } else if (lo == 0xf) {
  211. if (!control.ticks_counter) control.channel[p_track].channel_volume += hi;
  212. }
  213. if (control.channel[p_track].channel_volume < 0) control.channel[p_track].channel_volume = 0;
  214. if (control.channel[p_track].channel_volume > 64) control.channel[p_track].channel_volume = 64;
  215. }
  216. void CPPlayer::do_tremolo(int p_track) {
  217. uint8_t q;
  218. int16_t temp = 0;
  219. if ((control.ticks_counter == 0) && control.channel[p_track].row_has_note) control.channel[p_track].tremolo_position = 0;
  220. q = (control.channel[p_track].tremolo_position >> 2) & 0x1f;
  221. switch (control.channel[p_track].tremolo_type) {
  222. case 0: /* sine */
  223. temp = vibrato_table[q];
  224. break;
  225. case 1: /* ramp down */
  226. q <<= 3;
  227. if (control.channel[p_track].tremolo_position < 0) q = 255 - q;
  228. temp = q;
  229. break;
  230. case 2: /* square wave */
  231. temp = 255;
  232. break;
  233. case 3: /* random */
  234. temp = cp_random_generate(&control.random_seed) % 256; //getrandom(256);
  235. break;
  236. }
  237. temp *= control.channel[p_track].tremolo_depth;
  238. temp >>= 7;
  239. if (control.channel[p_track].tremolo_position >= 0) {
  240. control.channel[p_track].volume = control.channel[p_track].aux_volume + temp;
  241. if (control.channel[p_track].volume > 64) control.channel[p_track].volume = 64;
  242. } else {
  243. control.channel[p_track].volume = control.channel[p_track].aux_volume - temp;
  244. if (control.channel[p_track].volume < 0) control.channel[p_track].volume = 0;
  245. }
  246. /*if (control.ticks_counter)*/ control.channel[p_track].tremolo_position += control.channel[p_track].tremolo_speed;
  247. }
  248. void CPPlayer::do_arpegio(int p_track) {
  249. uint8_t note, dat;
  250. //note=control.channel[p_track].note;
  251. note = 0;
  252. if (control.channel[p_track].current_parameter) {
  253. control.channel[p_track].arpegio_info = control.channel[p_track].current_parameter;
  254. }
  255. dat = control.channel[p_track].arpegio_info;
  256. if (dat) {
  257. switch (control.ticks_counter % 3) {
  258. case 1: {
  259. note += (dat >> 4);
  260. } break;
  261. case 2: {
  262. note += (dat & 0xf);
  263. } break;
  264. }
  265. if (song->has_linear_slides()) {
  266. control.channel[p_track].period = control.channel[p_track].aux_period - cp_intabs(get_period((uint16_t)46, 0) - get_period((uint16_t)44, 0)) * note;
  267. } else if (control.channel[p_track].sample_ptr) {
  268. control.channel[p_track].period = get_period((((uint16_t)control.channel[p_track].note) + note) << 1, CPSampleManager::get_singleton()->get_c5_freq((control.channel[p_track].sample_ptr->get_sample_data())));
  269. }
  270. control.channel[p_track].has_own_period = true;
  271. }
  272. }
  273. void CPPlayer::do_retrig(int p_track) {
  274. uint8_t inf;
  275. inf = control.channel[p_track].current_parameter;
  276. if (inf) {
  277. control.channel[p_track].retrig_volslide = inf >> 4;
  278. control.channel[p_track].retrig_speed = inf & 0xf;
  279. }
  280. /* only retrigger if low nibble > 0 */
  281. if (control.channel[p_track].retrig_speed > 0) {
  282. if (!control.channel[p_track].retrig_counter) {
  283. /* when retrig counter reaches 0, reset counter and restart the
  284. sample */
  285. if (control.channel[p_track].kick != KICK_NOTE) control.channel[p_track].kick = KICK_NOTEOFF;
  286. control.channel[p_track].retrig_counter = control.channel[p_track].retrig_speed;
  287. if ((control.ticks_counter) /*||(pf->flags&UF_S3MSLIDES)*/) {
  288. switch (control.channel[p_track].retrig_volslide) {
  289. case 1:
  290. case 2:
  291. case 3:
  292. case 4:
  293. case 5:
  294. control.channel[p_track].aux_volume -= (1 << (control.channel[p_track].retrig_volslide - 1));
  295. break;
  296. case 6:
  297. control.channel[p_track].aux_volume = (2 * control.channel[p_track].aux_volume) / 3;
  298. break;
  299. case 7:
  300. control.channel[p_track].aux_volume >>= 1;
  301. break;
  302. case 9:
  303. case 0xa:
  304. case 0xb:
  305. case 0xc:
  306. case 0xd:
  307. control.channel[p_track].aux_volume += (1 << (control.channel[p_track].retrig_volslide - 9));
  308. break;
  309. case 0xe:
  310. control.channel[p_track].aux_volume = (3 * control.channel[p_track].aux_volume) >> 1;
  311. break;
  312. case 0xf:
  313. control.channel[p_track].aux_volume = control.channel[p_track].aux_volume << 1;
  314. break;
  315. }
  316. if (control.channel[p_track].aux_volume < 0)
  317. control.channel[p_track].aux_volume = 0;
  318. else if (control.channel[p_track].aux_volume > 64)
  319. control.channel[p_track].aux_volume = 64;
  320. }
  321. }
  322. control.channel[p_track].retrig_counter--; /* countdown */
  323. }
  324. }
  325. void CPPlayer::do_global_volume_slide(int p_track) {
  326. uint8_t lo, hi, inf;
  327. inf = control.channel[p_track].current_parameter;
  328. if (inf) control.channel[p_track].global_volume_slide_info = inf;
  329. inf = control.channel[p_track].global_volume_slide_info;
  330. lo = inf & 0xf;
  331. hi = inf >> 4;
  332. if (!lo) {
  333. if (control.ticks_counter) control.global_volume += hi;
  334. } else if (!hi) {
  335. if (control.ticks_counter) control.global_volume -= lo;
  336. } else if (lo == 0xf) {
  337. if (!control.ticks_counter) control.global_volume += hi;
  338. } else if (hi == 0xf) {
  339. if (!control.ticks_counter) control.global_volume -= lo;
  340. }
  341. if (control.global_volume < 0) control.global_volume = 0;
  342. if (control.global_volume > 128) control.global_volume = 128;
  343. }
  344. void CPPlayer::do_panbrello(int p_track) {
  345. uint8_t q;
  346. int32_t temp = 0;
  347. q = control.channel[p_track].panbrello_position;
  348. switch (control.channel[p_track].panbrello_type) {
  349. case 0: { /* sine */
  350. temp = panbrello_table[q];
  351. } break;
  352. case 1: { /* square wave */
  353. temp = (q < 0x80) ? 64 : 0;
  354. } break;
  355. case 2: { /* ramp down */
  356. q <<= 3;
  357. temp = q;
  358. } break;
  359. case 3: { /* random */
  360. if (control.channel[p_track].panbrello_position >= control.channel[p_track].panbrello_speed) {
  361. control.channel[p_track].panbrello_position = 0;
  362. temp = cp_random_generate(&control.random_seed) % 256; //getrandom(256);
  363. }
  364. } break;
  365. }
  366. temp = temp * (int)control.channel[p_track].panbrello_depth / 0xF;
  367. temp <<= 1;
  368. if (control.channel[p_track].channel_panning != PAN_SURROUND)
  369. temp += control.channel[p_track].channel_panning;
  370. control.channel[p_track].panning = (temp < PAN_LEFT) ? PAN_LEFT : (temp > PAN_RIGHT ? PAN_RIGHT : temp);
  371. control.channel[p_track].panbrello_position += control.channel[p_track].panbrello_speed;
  372. }
  373. /******************
  374. S effect
  375. *******************/
  376. void CPPlayer::do_effect_S(int p_track) {
  377. uint8_t inf, c, dat;
  378. dat = control.channel[p_track].current_parameter;
  379. inf = dat & 0xf;
  380. c = dat >> 4;
  381. if (!dat) {
  382. c = control.channel[p_track].current_S_effect;
  383. inf = control.channel[p_track].current_S_data;
  384. } else {
  385. control.channel[p_track].current_S_effect = c;
  386. control.channel[p_track].current_S_data = inf;
  387. }
  388. switch (c) {
  389. case 1: { /* S1x set glissando voice */
  390. // this is unsupported in IT!
  391. control.channel[p_track].chorus_send = inf * 0xFF / 0xF;
  392. } break;
  393. case 2: /* S2x set finetune */
  394. //Also not supported!
  395. break;
  396. case 3: /* S3x set vibrato waveform */
  397. if (inf < 4) control.channel[p_track].vibrato_type = inf;
  398. break;
  399. case 4: /* S4x set tremolo waveform */
  400. if (inf < 4) control.channel[p_track].tremolo_type = inf;
  401. break;
  402. case 5: /* S5x panbrello */
  403. if (inf < 4) control.channel[p_track].panbrello_type = inf;
  404. break;
  405. case 6: { /* S6x delay x number of frames (patdly) */
  406. if (control.ticks_counter) break;
  407. if (!control.pattern_delay_2) control.pattern_delay_1 = inf + 1; /* only once, when vbtick=0 */
  408. } break;
  409. case 7: /* S7x instrument / NNA commands */
  410. if (!song->has_instruments())
  411. break;
  412. switch (inf) {
  413. case 0x3: {
  414. control.channel[p_track].NNA_type = CPInstrument::NNA_NOTE_CUT;
  415. } break;
  416. case 0x4: {
  417. control.channel[p_track].NNA_type = CPInstrument::NNA_NOTE_CONTINUE;
  418. } break;
  419. case 0x5: {
  420. control.channel[p_track].NNA_type = CPInstrument::NNA_NOTE_OFF;
  421. } break;
  422. case 0x6: {
  423. control.channel[p_track].NNA_type = CPInstrument::NNA_NOTE_FADE;
  424. } break;
  425. case 0x7: {
  426. if (control.channel[p_track].slave_voice)
  427. control.channel[p_track].slave_voice->volume_envelope_ctrl.active = false;
  428. } break;
  429. case 0x8: {
  430. if (control.channel[p_track].slave_voice)
  431. control.channel[p_track].slave_voice->volume_envelope_ctrl.active = true;
  432. } break;
  433. case 0x9: {
  434. if (control.channel[p_track].slave_voice)
  435. control.channel[p_track].slave_voice->panning_envelope_ctrl.active = false;
  436. } break;
  437. case 0xA: {
  438. if (control.channel[p_track].slave_voice)
  439. control.channel[p_track].slave_voice->panning_envelope_ctrl.active = true;
  440. } break;
  441. case 0xB: {
  442. if (control.channel[p_track].slave_voice)
  443. control.channel[p_track].slave_voice->pitch_envelope_ctrl.active = false;
  444. } break;
  445. case 0xC: {
  446. if (control.channel[p_track].slave_voice)
  447. control.channel[p_track].slave_voice->pitch_envelope_ctrl.active = true;
  448. } break;
  449. }
  450. break;
  451. break;
  452. case 8: { /* S8x set panning position */
  453. // if (pf->panflag) {
  454. if (inf <= 8)
  455. inf <<= 4;
  456. else
  457. inf *= 17;
  458. control.channel[p_track].panning = control.channel[p_track].channel_panning = inf;
  459. // }
  460. } break;
  461. case 9: { /* S9x set surround sound */
  462. //if (pf->panflag)
  463. control.channel[p_track].panning = control.channel[p_track].channel_panning = PAN_SURROUND;
  464. } break;
  465. case 0xA: { /* SAy set high order sample offset yxx00h */
  466. if (control.channel[p_track].current_parameter) control.channel[p_track].hi_offset = (int32_t)inf << 16;
  467. control.channel[p_track].sample_start_index = control.channel[p_track].hi_offset | control.channel[p_track].lo_offset;
  468. } break;
  469. case 0xB: { /* SBx pattern loop */
  470. if (control.ticks_counter) break;
  471. if (inf) { /* set reppos or repcnt ? */
  472. /* set repcnt, so check if repcnt already is set, which means we
  473. are already looping */
  474. if (control.channel[p_track].pattern_loop_count > 0)
  475. control.channel[p_track].pattern_loop_count--; /* already looping, decrease counter */
  476. else {
  477. control.channel[p_track].pattern_loop_count = inf; /* not yet looping, so set repcnt */
  478. }
  479. if (control.channel[p_track].pattern_loop_count > 0) { /* jump to reppos if repcnt>0 */
  480. control.position = control.previous_position; // This will also anulate any Cxx or break..
  481. control.position.current_row = control.channel[p_track].pattern_loop_position;
  482. control.position.forbid_jump = true;
  483. }
  484. } else {
  485. control.channel[p_track].pattern_loop_position = control.position.current_row - 1;
  486. }
  487. } break;
  488. case 0xC: { /* SCx notecut */
  489. if (control.ticks_counter >= inf) {
  490. control.channel[p_track].aux_volume = 0;
  491. control.channel[p_track].note_end_flags |= END_NOTE_OFF;
  492. control.channel[p_track].note_end_flags |= END_NOTE_KILL;
  493. }
  494. } break;
  495. case 0xD: { /* SDx notedelay */
  496. if (!control.ticks_counter) {
  497. control.channel[p_track].note_delay = inf;
  498. } else if (control.channel[p_track].note_delay) {
  499. control.channel[p_track].note_delay--;
  500. }
  501. } break;
  502. case 0xF: { /* SEx patterndelay */
  503. if (control.ticks_counter) break;
  504. if (!control.pattern_delay_2) control.pattern_delay_1 = inf + 1; /* only once, when vbtick=0 */
  505. } break;
  506. }
  507. }
  508. /*********************
  509. volume effects
  510. **********************/
  511. void CPPlayer::run_volume_column_effects(int p_track) {
  512. uint8_t param = control.channel[p_track].current_volume_parameter;
  513. switch ('A' + control.channel[p_track].current_volume_command) {
  514. case 'A': {
  515. if (param > 0)
  516. control.channel[p_track].volcol_volume_slide = param;
  517. else
  518. param = control.channel[p_track].volcol_volume_slide;
  519. do_volume_slide(p_track, param * 0x10 + 0xF);
  520. } break;
  521. case 'B': {
  522. if (param > 0)
  523. control.channel[p_track].volcol_volume_slide = param;
  524. else
  525. param = control.channel[p_track].volcol_volume_slide;
  526. do_volume_slide(p_track, 0xF0 + param);
  527. } break;
  528. case 'C': {
  529. if (param > 0)
  530. control.channel[p_track].volcol_volume_slide = param;
  531. else
  532. param = control.channel[p_track].volcol_volume_slide;
  533. do_volume_slide(p_track, param * 0x10);
  534. } break;
  535. case 'D': {
  536. if (param > 0)
  537. control.channel[p_track].volcol_volume_slide = param;
  538. else
  539. param = control.channel[p_track].volcol_volume_slide;
  540. do_volume_slide(p_track, param);
  541. } break;
  542. case 'E': {
  543. do_pitch_slide_down(p_track, param << 2);
  544. } break;
  545. case 'F': {
  546. do_pitch_slide_up(p_track, param << 2);
  547. } break;
  548. case 'G': {
  549. const uint8_t slide_table[] = { 0, 1, 4, 8, 16, 32, 64, 96, 128, 255 };
  550. if (param) {
  551. control.channel[p_track].portamento_speed = slide_table[param];
  552. }
  553. if (control.channel[p_track].period && (control.channel[p_track].old_note <= 120)) {
  554. if ((!control.ticks_counter) && (control.channel[p_track].new_instrument)) {
  555. //control.channel[p_track].kick=KICK_NOTE;
  556. //control.channel[p_track].sample_start_index=0; // < am i stupid?
  557. } else {
  558. control.channel[p_track].kick = (control.channel[p_track].kick == KICK_NOTE) ? KICK_ENVELOPE : KICK_NOTHING;
  559. do_pitch_slide_to_note(p_track);
  560. control.channel[p_track].has_own_period = true;
  561. }
  562. }
  563. } break;
  564. case 'H': {
  565. if (!control.ticks_counter) {
  566. if (param & 0x0f) control.channel[p_track].vibrato_depth = param;
  567. }
  568. control.channel[p_track].doing_vibrato = true;
  569. if (control.external_vibrato) break;
  570. if (control.channel[p_track].period) {
  571. do_vibrato(p_track, false);
  572. control.channel[p_track].has_own_period = true;
  573. }
  574. } break;
  575. }
  576. }
  577. /*********************
  578. table
  579. **********************/
  580. void CPPlayer::run_effects(int p_track) {
  581. switch ('A' + control.channel[p_track].current_command) {
  582. case 'A': {
  583. if ((control.ticks_counter > 0) || (control.pattern_delay_2 > 0)) break;
  584. int new_speed;
  585. new_speed = control.channel[p_track].current_parameter % 128;
  586. if (new_speed > 0) {
  587. control.speed = new_speed;
  588. control.ticks_counter = 0;
  589. }
  590. } break;
  591. case 'B': {
  592. int next_order;
  593. if (control.ticks_counter || control.position.forbid_jump) break;
  594. control.position.current_row = 0;
  595. if (control.play_mode == PLAY_PATTERN) break;
  596. next_order = get_song_next_order_idx(song, (int)control.channel[p_track].current_parameter - 1);
  597. if (next_order != -1) {
  598. // Do we have a "next order?"
  599. control.position.current_pattern = song->get_order(next_order);
  600. control.position.force_next_order = next_order;
  601. } else {
  602. // no, probably the user deleted the orderlist.
  603. control.play_mode = PLAY_NOTHING;
  604. reset();
  605. }
  606. } break;
  607. case 'C': {
  608. int next_order;
  609. if (control.ticks_counter || control.position.forbid_jump) break;
  610. control.position.current_row = control.channel[p_track].current_parameter;
  611. if (control.play_mode == PLAY_PATTERN) {
  612. if (control.position.current_row >= song->get_pattern(control.position.current_pattern)->get_length()) {
  613. control.position.current_row = 0;
  614. }
  615. break;
  616. }
  617. next_order = get_song_next_order_idx(song, (int)control.position.current_order);
  618. if (next_order != -1) {
  619. // Do we have a "next order?"
  620. control.position.current_pattern = song->get_order(next_order);
  621. if (control.position.current_row >= song->get_pattern(song->get_order(next_order))->get_length()) {
  622. control.position.current_row = 0;
  623. }
  624. control.position.force_next_order = next_order;
  625. } else {
  626. // no, probably the user deleted the orderlist.
  627. control.play_mode = PLAY_NOTHING;
  628. reset();
  629. }
  630. } break;
  631. case 'D': {
  632. uint8_t inf;
  633. //explicitslides=1;
  634. inf = control.channel[p_track].current_parameter;
  635. if (inf)
  636. control.channel[p_track].volume_slide_info = inf;
  637. else
  638. inf = control.channel[p_track].volume_slide_info;
  639. do_volume_slide(p_track, inf);
  640. } break;
  641. case 'E': {
  642. uint8_t inf;
  643. inf = control.channel[p_track].current_parameter;
  644. do_pitch_slide_down(p_track, inf);
  645. } break;
  646. case 'F': {
  647. uint8_t inf;
  648. inf = control.channel[p_track].current_parameter;
  649. do_pitch_slide_up(p_track, inf);
  650. } break;
  651. case 'G': {
  652. if (control.channel[p_track].current_parameter) {
  653. control.channel[p_track].portamento_speed = control.channel[p_track].current_parameter;
  654. }
  655. if (control.channel[p_track].period && (control.channel[p_track].old_note <= 120)) {
  656. if ((!control.ticks_counter) && (control.channel[p_track].new_instrument)) {
  657. control.channel[p_track].kick = KICK_NOTE;
  658. control.channel[p_track].sample_start_index = 0;
  659. } else {
  660. control.channel[p_track].kick = (control.channel[p_track].kick == KICK_NOTE) ? KICK_ENVELOPE : KICK_NOTHING;
  661. }
  662. do_pitch_slide_to_note(p_track);
  663. control.channel[p_track].has_own_period = true;
  664. }
  665. } break;
  666. case 'H': {
  667. uint8_t dat;
  668. control.channel[p_track].doing_vibrato = true;
  669. dat = control.channel[p_track].current_parameter;
  670. if (!control.ticks_counter) {
  671. if (dat & 0x0f) control.channel[p_track].vibrato_depth = dat & 0xf;
  672. if (dat & 0xf0) control.channel[p_track].vibrato_speed = (dat & 0xf0) >> 2;
  673. }
  674. if (control.external_vibrato) break;
  675. if (control.channel[p_track].period) {
  676. do_vibrato(p_track, false);
  677. control.channel[p_track].has_own_period = true;
  678. }
  679. } break;
  680. case 'I': {
  681. do_tremor(p_track);
  682. control.channel[p_track].has_own_volume = true;
  683. } break;
  684. case 'J': {
  685. do_arpegio(p_track);
  686. } break;
  687. case 'K': {
  688. uint8_t inf;
  689. //explicitslides=1;
  690. inf = control.channel[p_track].current_parameter;
  691. control.channel[p_track].doing_vibrato = true;
  692. if (inf)
  693. control.channel[p_track].volume_slide_info = inf;
  694. else
  695. inf = control.channel[p_track].volume_slide_info;
  696. do_volume_slide(p_track, inf);
  697. if (control.external_vibrato) break;
  698. if (control.channel[p_track].period) {
  699. do_vibrato(p_track, false);
  700. control.channel[p_track].has_own_period = true;
  701. }
  702. } break;
  703. case 'L': {
  704. uint8_t inf;
  705. //explicitslides=1;
  706. inf = control.channel[p_track].current_parameter;
  707. if (inf)
  708. control.channel[p_track].volume_slide_info = inf;
  709. else
  710. inf = control.channel[p_track].volume_slide_info;
  711. do_volume_slide(p_track, inf);
  712. if (control.channel[p_track].period && (control.channel[p_track].old_note <= 120)) {
  713. if ((!control.ticks_counter) && (control.channel[p_track].new_instrument)) {
  714. control.channel[p_track].kick = KICK_NOTE;
  715. control.channel[p_track].sample_start_index = 0;
  716. } else {
  717. control.channel[p_track].kick = (control.channel[p_track].kick == KICK_NOTE) ? KICK_ENVELOPE : KICK_NOTHING;
  718. }
  719. do_pitch_slide_to_note(p_track);
  720. control.channel[p_track].has_own_period = true;
  721. }
  722. } break;
  723. case 'M': {
  724. control.channel[p_track].channel_volume = control.channel[p_track].current_parameter;
  725. if (control.channel[p_track].channel_volume > 64)
  726. control.channel[p_track].channel_volume = 64;
  727. else if (control.channel[p_track].channel_volume < 0)
  728. control.channel[p_track].channel_volume = 0;
  729. } break;
  730. case 'N': {
  731. do_channel_volume_slide(p_track);
  732. }
  733. case 'O': {
  734. if (!control.ticks_counter) {
  735. if (control.channel[p_track].current_parameter) control.channel[p_track].lo_offset = (uint16_t)control.channel[p_track].current_parameter << 8;
  736. control.channel[p_track].sample_start_index = control.channel[p_track].hi_offset | control.channel[p_track].lo_offset;
  737. //if ((control.channel[p_track].sample_ptr!=NULL)&&(control.channel[p_track].sample_start_index>control.channel[p_track].sample_ptr->data.size)) {
  738. //TODO, O effect
  739. //a->start=a->s->flags&(SF_LOOP|SF_BIDI)?a->s->loopstart:a->s->length;
  740. //}
  741. }
  742. } break;
  743. case 'P': {
  744. do_pan_slide(p_track);
  745. } break;
  746. case 'Q': {
  747. do_retrig(p_track);
  748. } break;
  749. case 'R': {
  750. uint8_t dat;
  751. if (control.channel[p_track].current_parameter) {
  752. control.channel[p_track].tremolo_info = control.channel[p_track].current_parameter;
  753. }
  754. dat = control.channel[p_track].tremolo_info;
  755. if (!control.ticks_counter && dat) {
  756. if (dat & 0x0f) control.channel[p_track].tremolo_depth = dat & 0xf;
  757. if (dat & 0xf0) control.channel[p_track].tremolo_speed = (dat & 0xf0) >> 2;
  758. }
  759. do_tremolo(p_track);
  760. control.channel[p_track].has_own_volume = true;
  761. } break;
  762. case 'S': {
  763. do_effect_S(p_track);
  764. } break;
  765. case 'T': {
  766. uint8_t dat;
  767. int16_t temp = control.tempo;
  768. if (control.pattern_delay_2) return;
  769. if (control.channel[p_track].current_parameter) {
  770. control.channel[p_track].tempo_slide_info = control.channel[p_track].current_parameter;
  771. }
  772. dat = control.channel[p_track].tempo_slide_info;
  773. if (dat >= 0x20) {
  774. if (control.ticks_counter) break;
  775. control.tempo = dat;
  776. } else {
  777. if (!control.ticks_counter) break;
  778. if (dat & 0x10) {
  779. temp += (dat & 0x0f);
  780. } else {
  781. temp -= dat;
  782. }
  783. control.tempo = (temp > 255) ? 255 : (temp < 0x20 ? 0x20 : temp);
  784. }
  785. } break;
  786. case 'U': {
  787. uint8_t dat;
  788. dat = control.channel[p_track].current_parameter;
  789. control.channel[p_track].doing_vibrato = true;
  790. if (!control.ticks_counter) {
  791. if (dat & 0x0f) control.channel[p_track].vibrato_depth = dat & 0xf;
  792. if (dat & 0xf0) control.channel[p_track].vibrato_speed = (dat & 0xf0) >> 2;
  793. }
  794. if (control.external_vibrato) break;
  795. if (control.channel[p_track].period) {
  796. do_vibrato(p_track, true);
  797. control.channel[p_track].has_own_period = true;
  798. }
  799. } break;
  800. case 'V': {
  801. control.global_volume = control.channel[p_track].current_parameter;
  802. if (control.global_volume > 128) control.global_volume = 128;
  803. } break;
  804. case 'W': {
  805. do_global_volume_slide(p_track);
  806. } break;
  807. case 'X': {
  808. //sets both channel and current
  809. control.channel[p_track].channel_panning = control.channel[p_track].current_parameter;
  810. control.channel[p_track].panning = control.channel[p_track].current_parameter;
  811. } break;
  812. case 'Y': {
  813. uint8_t dat;
  814. if (control.channel[p_track].current_parameter) {
  815. control.channel[p_track].panbrello_info = control.channel[p_track].current_parameter;
  816. }
  817. dat = control.channel[p_track].panbrello_info;
  818. if (!control.ticks_counter) {
  819. if (dat & 0x0f) control.channel[p_track].panbrello_depth = (dat & 0xf);
  820. if (dat & 0xf0) control.channel[p_track].panbrello_speed = (dat & 0xf0) >> 4;
  821. }
  822. //if (pf->panflag)
  823. if (control.channel[p_track].panning != PAN_SURROUND) do_panbrello(p_track);
  824. } break;
  825. case 'Z': {
  826. //I DO! cuttoff!
  827. uint16_t dat = control.channel[p_track].current_parameter;
  828. if (dat < 0x80) {
  829. control.channel[p_track].filter.it_cutoff = dat * 2;
  830. if (control.channel[p_track].filter.it_cutoff > 0x80)
  831. control.channel[p_track].filter.it_cutoff++;
  832. } else if (dat < 0x90) {
  833. control.channel[p_track].filter.it_reso = (dat - 0x80) * 0x10;
  834. } else {
  835. control.channel[p_track].reverb_send = (dat - 0x90) * 255 / 0x6F;
  836. }
  837. } break;
  838. }
  839. }
  840. void CPPlayer::pre_process_effects() {
  841. // MP_VOICE *aout;
  842. int i;
  843. for (i = 0; i < CPPattern::WIDTH; i++) {
  844. //a=&pf->control[mp_channel];
  845. // if ((aout=a->slave)) {
  846. // a->fadevol=aout->fadevol;
  847. // a->period=aout->period;
  848. // if (a->kick==KICK_KEYOFF) a->keyoff=aout->keyoff;
  849. //}
  850. //if (!a->row) continue;
  851. //UniSetRow(a->row);
  852. control.channel[i].has_own_period = false;
  853. control.channel[i].has_own_volume = false;
  854. control.channel[i].doing_vibrato = false;
  855. //explicitslides=0;
  856. //pt_playeffects();
  857. if (control.ticks_counter < control.speed) {
  858. run_effects(i);
  859. run_volume_column_effects(i);
  860. }
  861. /* continue volume slide if necessary for XM and IT */
  862. //if (pf->flags&UF_BGSLIDES) {
  863. // if (!explicitslides && a->sliding)
  864. // DoS3MVolSlide(0);
  865. // else if (a->tmpvolume) a->sliding=explicitslides;
  866. //}
  867. if (!control.channel[i].has_own_period) control.channel[i].period = control.channel[i].aux_period;
  868. if (!control.channel[i].has_own_volume) control.channel[i].volume = control.channel[i].aux_volume;
  869. if ((control.channel[i].sample_ptr != NULL) && !(song->has_instruments() && (control.channel[i].instrument_ptr == NULL))) {
  870. if (song->has_instruments()) {
  871. control.channel[i].output_volume =
  872. (control.channel[i].volume * control.channel[i].sample_ptr->get_global_volume() * control.channel[i].instrument_ptr->get_volume_global_amount()) / 2048;
  873. control.channel[i].output_volume = control.channel[i].output_volume * control.channel[i].random_volume_variation / 100;
  874. } else {
  875. control.channel[i].output_volume =
  876. (control.channel[i].volume * control.channel[i].sample_ptr->get_global_volume()) >> 4;
  877. }
  878. if (control.channel[i].output_volume > 256) {
  879. control.channel[i].output_volume = 256;
  880. } else if (control.channel[i].output_volume < 0) {
  881. control.channel[i].output_volume = 0;
  882. }
  883. }
  884. }
  885. }