cp_song.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. /*************************************************************************/
  2. /* cp_song.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_song.h"
  31. void CPSong::set_name(const char *p_name) {
  32. if (p_name == NULL) {
  33. variables.name[0] = 0;
  34. return;
  35. }
  36. bool done = false;
  37. for (int i = 0; i < MAX_SONG_NAME; i++) {
  38. variables.name[i] = done ? 0 : p_name[i];
  39. if (!done && p_name[i] == 0)
  40. done = true;
  41. }
  42. variables.name[MAX_SONG_NAME - 1] = 0; /* just in case */
  43. }
  44. const char *CPSong::get_name() {
  45. return variables.name;
  46. }
  47. void CPSong::set_message(const char *p_message) {
  48. if (p_message == NULL) {
  49. variables.message[0] = 0;
  50. return;
  51. }
  52. bool done = false;
  53. for (int i = 0; i < MAX_MESSAGE_LEN; i++) {
  54. variables.message[i] = done ? 0 : p_message[i];
  55. if (!done && p_message[i] == 0)
  56. done = true;
  57. }
  58. variables.message[MAX_MESSAGE_LEN - 1] = 0; /* just in case */
  59. }
  60. const char *CPSong::get_message() {
  61. return variables.message;
  62. }
  63. void CPSong::set_row_highlight_minor(int p_hl_minor) {
  64. variables.row_highlight_minor = p_hl_minor;
  65. }
  66. int CPSong::get_row_highlight_minor() {
  67. return variables.row_highlight_minor;
  68. }
  69. void CPSong::set_row_highlight_major(int p_hl_major) {
  70. variables.row_highlight_major = p_hl_major;
  71. } /* 0 .. 256 */
  72. int CPSong::get_row_highlight_major() {
  73. return variables.row_highlight_major;
  74. } /* 0 .. 256 */
  75. void CPSong::set_mixing_volume(int p_mix_volume) {
  76. variables.mixing_volume = p_mix_volume;
  77. } /* 0 .. 128 */
  78. int CPSong::get_mixing_volume() {
  79. return variables.mixing_volume;
  80. } /* 0 .. 128 */
  81. void CPSong::set_global_volume(int p_global_volume) {
  82. initial_variables.global_volume = p_global_volume;
  83. } /* 0 .. 128 */
  84. int CPSong::get_global_volume() {
  85. return initial_variables.global_volume;
  86. } /* 0 .. 128 */
  87. void CPSong::set_stereo_separation(int p_separation) {
  88. variables.stereo_separation = p_separation;
  89. } /* 0 .. 128 */
  90. int CPSong::get_stereo_separation() {
  91. return variables.stereo_separation;
  92. } /* 0 .. 128 */
  93. void CPSong::set_stereo(bool p_stereo) {
  94. variables.use_stereo = p_stereo;
  95. }
  96. bool CPSong::is_stereo() {
  97. return variables.use_stereo;
  98. }
  99. void CPSong::set_instruments(bool p_instruments) {
  100. variables.use_instruments = p_instruments;
  101. }
  102. bool CPSong::has_instruments() {
  103. return variables.use_instruments;
  104. }
  105. void CPSong::set_linear_slides(bool p_linear_slides) {
  106. variables.use_linear_slides = p_linear_slides;
  107. }
  108. bool CPSong::has_linear_slides() {
  109. return variables.use_linear_slides;
  110. }
  111. void CPSong::set_old_effects(bool p_old_effects) {
  112. variables.old_effects = p_old_effects;
  113. }
  114. bool CPSong::has_old_effects() {
  115. return variables.old_effects;
  116. }
  117. void CPSong::set_compatible_gxx(bool p_compatible_gxx) {
  118. variables.compatible_gxx = p_compatible_gxx;
  119. }
  120. bool CPSong::has_compatible_gxx() {
  121. return variables.compatible_gxx;
  122. }
  123. void CPSong::set_speed(int p_speed) {
  124. CP_ERR_COND(p_speed < MIN_SPEED);
  125. CP_ERR_COND(p_speed > MAX_SPEED);
  126. initial_variables.speed = p_speed;
  127. } /* 1 .. 255 */
  128. int CPSong::get_speed() {
  129. return initial_variables.speed;
  130. } /* 1 .. 255 */
  131. void CPSong::set_tempo(int p_tempo) {
  132. CP_ERR_COND(p_tempo < MIN_TEMPO);
  133. CP_ERR_COND(p_tempo > MAX_TEMPO);
  134. initial_variables.tempo = p_tempo;
  135. } /* MIN_TEMPO .. MAX_TEMPO */
  136. int CPSong::get_tempo() {
  137. return initial_variables.tempo;
  138. } /* MIN_TEMPO .. MAX_TEMPO */
  139. void CPSong::set_channel_pan(int p_channel, int p_pan) {
  140. CP_FAIL_INDEX(p_channel, CPPattern::WIDTH);
  141. CP_FAIL_INDEX(p_pan, CHANNEL_MAX_PAN + 1);
  142. initial_variables.channel[p_channel].pan = p_pan;
  143. } /* 0 .. CHANNEL_MAX_PAN */
  144. int CPSong::get_channel_pan(int p_channel) {
  145. CP_FAIL_INDEX_V(p_channel, CPPattern::WIDTH, -1);
  146. return initial_variables.channel[p_channel].pan;
  147. }
  148. void CPSong::set_channel_volume(int p_channel, int p_volume) {
  149. CP_FAIL_INDEX(p_channel, CPPattern::WIDTH);
  150. CP_FAIL_INDEX(p_volume, CHANNEL_MAX_VOLUME + 1);
  151. initial_variables.channel[p_channel].volume = p_volume;
  152. } /* 0 .. CHANNEL_MAX_VOLUME */
  153. int CPSong::get_channel_volume(int p_channel) {
  154. CP_FAIL_INDEX_V(p_channel, CPPattern::WIDTH, -1);
  155. return initial_variables.channel[p_channel].volume;
  156. }
  157. void CPSong::set_channel_chorus(int p_channel, int p_chorus) {
  158. CP_FAIL_INDEX(p_channel, CPPattern::WIDTH);
  159. CP_FAIL_INDEX(p_chorus, CHANNEL_MAX_CHORUS + 1);
  160. initial_variables.channel[p_channel].chorus = p_chorus;
  161. } /* 0 .. CHANNEL_MAX_CHORUS */
  162. int CPSong::get_channel_chorus(int p_channel) {
  163. CP_FAIL_INDEX_V(p_channel, CPPattern::WIDTH, -1);
  164. return initial_variables.channel[p_channel].chorus;
  165. }
  166. void CPSong::set_channel_reverb(int p_channel, int p_reverb) {
  167. CP_FAIL_INDEX(p_channel, CPPattern::WIDTH);
  168. CP_FAIL_INDEX(p_reverb, CHANNEL_MAX_REVERB + 1);
  169. initial_variables.channel[p_channel].reverb = p_reverb;
  170. } /* 0 .. CHANNEL_MAX_CHORUS */
  171. int CPSong::get_channel_reverb(int p_channel) {
  172. CP_FAIL_INDEX_V(p_channel, CPPattern::WIDTH, -1);
  173. return initial_variables.channel[p_channel].reverb;
  174. }
  175. void CPSong::set_channel_surround(int p_channel, bool p_surround) {
  176. CP_FAIL_INDEX(p_channel, CPPattern::WIDTH);
  177. initial_variables.channel[p_channel].surround = p_surround;
  178. }
  179. bool CPSong::is_channel_surround(int p_channel) {
  180. CP_FAIL_INDEX_V(p_channel, CPPattern::WIDTH, false);
  181. return initial_variables.channel[p_channel].surround;
  182. }
  183. void CPSong::set_channel_mute(int p_channel, bool p_mute) {
  184. CP_FAIL_INDEX(p_channel, CPPattern::WIDTH);
  185. initial_variables.channel[p_channel].mute = p_mute;
  186. }
  187. bool CPSong::is_channel_mute(int p_channel) {
  188. CP_FAIL_INDEX_V(p_channel, CPPattern::WIDTH, false);
  189. return initial_variables.channel[p_channel].mute;
  190. }
  191. /* arrays of stuff */
  192. CPPattern *CPSong::get_pattern(int p_pattern) {
  193. CP_FAIL_INDEX_V(p_pattern, MAX_PATTERNS, NULL);
  194. return &pattern[p_pattern];
  195. }
  196. CPSample *CPSong::get_sample(int p_sample) {
  197. CP_FAIL_INDEX_V(p_sample, MAX_SAMPLES, NULL);
  198. return &sample[p_sample];
  199. }
  200. CPInstrument *CPSong::get_instrument(int p_instrument) {
  201. CP_FAIL_INDEX_V(p_instrument, MAX_INSTRUMENTS, NULL);
  202. return &instrument[p_instrument];
  203. }
  204. int CPSong::get_order(int p_order) {
  205. CP_FAIL_INDEX_V(p_order, MAX_ORDERS, CP_ORDER_NONE);
  206. return order[p_order];
  207. }
  208. void CPSong::set_order(int p_order, int p_pattern) {
  209. CP_FAIL_INDEX(p_order, MAX_ORDERS);
  210. order[p_order] = p_pattern;
  211. }
  212. void CPSong::clear_instrument_with_samples(int p_instrument) {
  213. CPInstrument *ins = get_instrument(p_instrument);
  214. if (!ins)
  215. return;
  216. for (int i = 0; i < CPNote::NOTES; i++) {
  217. CPSample *s = get_sample(ins->get_sample_number(i));
  218. if (!s)
  219. continue;
  220. if (s->get_sample_data().is_null())
  221. continue;
  222. s->reset();
  223. }
  224. ins->reset();
  225. }
  226. void CPSong::make_instrument_from_sample(int p_sample) {
  227. if (!has_instruments())
  228. return;
  229. CP_ERR_COND(!get_sample(p_sample));
  230. for (int i = 0; i < MAX_INSTRUMENTS; i++) {
  231. CPInstrument *ins = get_instrument(i);
  232. bool empty_slot = true;
  233. for (int n = 0; n < CPNote::NOTES; n++) {
  234. if (ins->get_sample_number(n) < MAX_SAMPLES) {
  235. empty_slot = false;
  236. break;
  237. }
  238. }
  239. if (!empty_slot)
  240. continue;
  241. for (int n = 0; n < CPNote::NOTES; n++) {
  242. ins->set_sample_number(n, p_sample);
  243. ins->set_note_number(n, n);
  244. }
  245. ins->set_name(get_sample(p_sample)->get_name());
  246. break;
  247. }
  248. }
  249. void CPSong::make_instruments_from_samples() {
  250. for (int i = 0; i < MAX_SAMPLES; i++) {
  251. CPInstrument *ins = get_instrument(i);
  252. if (!ins)
  253. continue;
  254. ins->reset();
  255. CPSample *s = get_sample(i);
  256. if (!s)
  257. continue;
  258. ins->set_name(s->get_name());
  259. if (s->get_sample_data().is_null())
  260. continue;
  261. for (int j = 0; j < CPNote::NOTES; j++)
  262. ins->set_sample_number(j, i);
  263. }
  264. }
  265. void CPSong::reset(bool p_clear_patterns, bool p_clear_samples, bool p_clear_instruments, bool p_clear_variables) {
  266. if (p_clear_variables) {
  267. variables.name[0] = 0;
  268. variables.message[0] = 0;
  269. variables.row_highlight_major = 16;
  270. variables.row_highlight_minor = 4;
  271. variables.mixing_volume = 48;
  272. variables.old_effects = false;
  273. if (p_clear_instruments) //should not be cleared, if not clearing instruments!!
  274. variables.use_instruments = false;
  275. variables.stereo_separation = 128;
  276. variables.use_linear_slides = true;
  277. variables.use_stereo = true;
  278. initial_variables.global_volume = 128;
  279. initial_variables.speed = 6;
  280. initial_variables.tempo = 125;
  281. for (int i = 0; i < CPPattern::WIDTH; i++) {
  282. initial_variables.channel[i].pan = 32;
  283. initial_variables.channel[i].volume = CHANNEL_MAX_VOLUME;
  284. initial_variables.channel[i].mute = false;
  285. initial_variables.channel[i].surround = false;
  286. initial_variables.channel[i].chorus = 0;
  287. initial_variables.channel[i].reverb = 0;
  288. }
  289. effects.chorus.delay_ms = 6;
  290. effects.chorus.separation_ms = 3;
  291. effects.chorus.depth_ms10 = 6,
  292. effects.chorus.speed_hz10 = 5;
  293. effects.reverb_mode = REVERB_MODE_ROOM;
  294. }
  295. if (p_clear_samples) {
  296. for (int i = 0; i < MAX_SAMPLES; i++)
  297. get_sample(i)->reset();
  298. }
  299. if (p_clear_instruments) {
  300. for (int i = 0; i < MAX_INSTRUMENTS; i++)
  301. get_instrument(i)->reset();
  302. }
  303. if (p_clear_patterns) {
  304. for (int i = 0; i < MAX_PATTERNS; i++)
  305. get_pattern(i)->clear();
  306. for (int i = 0; i < MAX_ORDERS; i++)
  307. set_order(i, CP_ORDER_NONE);
  308. }
  309. }
  310. CPSong::ReverbMode CPSong::get_reverb_mode() {
  311. return effects.reverb_mode;
  312. }
  313. void CPSong::set_reverb_mode(ReverbMode p_mode) {
  314. effects.reverb_mode = p_mode;
  315. }
  316. void CPSong::set_chorus_delay_ms(int p_amount) {
  317. effects.chorus.delay_ms = p_amount;
  318. }
  319. void CPSong::set_chorus_separation_ms(int p_amount) {
  320. effects.chorus.separation_ms = p_amount;
  321. }
  322. void CPSong::set_chorus_depth_ms10(int p_amount) {
  323. effects.chorus.depth_ms10 = p_amount;
  324. }
  325. void CPSong::set_chorus_speed_hz10(int p_amount) {
  326. effects.chorus.speed_hz10 = p_amount;
  327. }
  328. int CPSong::get_chorus_delay_ms() {
  329. return effects.chorus.delay_ms;
  330. }
  331. int CPSong::get_chorus_separation_ms() {
  332. return effects.chorus.separation_ms;
  333. }
  334. int CPSong::get_chorus_depth_ms10() {
  335. return effects.chorus.depth_ms10;
  336. }
  337. int CPSong::get_chorus_speed_hz10() {
  338. return effects.chorus.speed_hz10;
  339. }
  340. void CPSong::cleanup_unused_patterns() {
  341. for (int i = 0; i < MAX_PATTERNS; i++) {
  342. bool used = false;
  343. if (get_pattern(i)->is_empty())
  344. continue;
  345. for (int j = 0; j < MAX_ORDERS; j++) {
  346. if (get_order(j) == i) {
  347. used = true;
  348. }
  349. }
  350. if (!used)
  351. get_pattern(i)->clear();
  352. }
  353. }
  354. void CPSong::cleanup_unused_instruments() {
  355. if (!has_instruments())
  356. return;
  357. bool instr_found[MAX_INSTRUMENTS];
  358. for (int i = 0; i < MAX_INSTRUMENTS; i++)
  359. instr_found[i] = false;
  360. for (int i = 0; i < MAX_PATTERNS; i++) {
  361. if (get_pattern(i)->is_empty())
  362. continue;
  363. for (int row = 0; row < get_pattern(i)->get_length(); row++) {
  364. for (int col = 0; col < CPPattern::WIDTH; col++) {
  365. CPNote n;
  366. n = get_pattern(i)->get_note(col, row);
  367. if (n.instrument < MAX_INSTRUMENTS)
  368. instr_found[n.instrument] = true;
  369. }
  370. }
  371. }
  372. for (int i = 0; i < MAX_INSTRUMENTS; i++)
  373. if (!instr_found[i])
  374. get_instrument(i)->reset();
  375. }
  376. void CPSong::cleanup_unused_samples() {
  377. if (!has_instruments())
  378. return;
  379. bool sample_found[MAX_SAMPLES];
  380. for (int i = 0; i < MAX_INSTRUMENTS; i++)
  381. sample_found[i] = false;
  382. for (int i = 0; i < MAX_PATTERNS; i++) {
  383. if (get_pattern(i)->is_empty())
  384. continue;
  385. for (int row = 0; row < get_pattern(i)->get_length(); row++) {
  386. for (int col = 0; col < CPPattern::WIDTH; col++) {
  387. CPNote n;
  388. n = get_pattern(i)->get_note(col, row);
  389. if (n.instrument >= MAX_SAMPLES)
  390. continue;
  391. if (has_instruments()) {
  392. for (int nt = 0; nt < CPNote::NOTES; nt++) {
  393. int smp = get_instrument(n.instrument)->get_sample_number(nt);
  394. if (smp < MAX_SAMPLES)
  395. sample_found[smp] = true;
  396. }
  397. } else {
  398. if (n.instrument < MAX_SAMPLES)
  399. sample_found[n.instrument] = true;
  400. }
  401. }
  402. }
  403. }
  404. for (int i = 0; i < MAX_SAMPLES; i++)
  405. if (!sample_found[i])
  406. get_sample(i)->reset();
  407. }
  408. void CPSong::cleanup_unused_orders() {
  409. bool finito = false;
  410. for (int j = 0; j < MAX_ORDERS; j++) {
  411. if (get_order(j) == CP_ORDER_NONE)
  412. finito = true;
  413. if (finito)
  414. set_order(j, CP_ORDER_NONE);
  415. }
  416. }
  417. void CPSong::clear_all_default_pan() {
  418. for (int i = 0; i < MAX_INSTRUMENTS; i++)
  419. get_instrument(i)->set_pan_default_enabled(false); //die!
  420. for (int i = 0; i < MAX_SAMPLES; i++)
  421. get_sample(i)->set_pan_enabled(false); //die!
  422. }
  423. void CPSong::clear_all_default_vol() {
  424. for (int i = 0; i < MAX_SAMPLES; i++)
  425. get_sample(i)->set_default_volume(64); //die!
  426. for (int i = 0; i < MAX_INSTRUMENTS; i++)
  427. get_instrument(i)->set_volume_global_amount(CPInstrument::MAX_VOLUME);
  428. }
  429. int CPSong::get_order_in_use_count() {
  430. int order_count = 0;
  431. for (int i = (MAX_ORDERS - 1); i >= 0; i--) {
  432. if (get_order(i) != CP_ORDER_NONE) {
  433. order_count = i + 1;
  434. break;
  435. }
  436. }
  437. return order_count;
  438. }
  439. int CPSong::get_pattern_in_use_count() {
  440. int pattern_count = 0;
  441. for (int i = (CPSong::MAX_PATTERNS - 1); i >= 0; i--) {
  442. if (!get_pattern(i)->is_empty()) {
  443. pattern_count = i + 1;
  444. break;
  445. }
  446. }
  447. return pattern_count;
  448. }
  449. int CPSong::get_instrument_in_use_count() {
  450. int instrument_count = 0;
  451. for (int i = (CPSong::MAX_INSTRUMENTS - 1); i >= 0; i--) {
  452. CPInstrument *ins = get_instrument(i);
  453. bool in_use = false;
  454. for (int s = 0; s < CPNote::NOTES; s++) {
  455. int smp_idx = ins->get_sample_number(s);
  456. if (smp_idx < 0 || smp_idx >= CPSong::MAX_SAMPLES)
  457. continue;
  458. if (!get_sample(smp_idx)->get_sample_data().is_null()) {
  459. in_use = true;
  460. break;
  461. }
  462. }
  463. if (in_use) {
  464. instrument_count = i + 1;
  465. break;
  466. }
  467. }
  468. return instrument_count;
  469. }
  470. #include <stdio.h>
  471. int CPSong::get_channels_in_use() {
  472. int max = 0;
  473. for (int p = 0; p < CPSong::MAX_PATTERNS; p++) {
  474. CPPattern *pat = get_pattern(p);
  475. if (pat->is_empty())
  476. continue;
  477. for (int c = (CPPattern::WIDTH - 1); c >= 0; c--) {
  478. if (c < max)
  479. break;
  480. bool has_note = false;
  481. for (int r = 0; r < pat->get_length(); r++) {
  482. CPNote n = pat->get_note(c, r);
  483. if (!n.is_empty()) {
  484. has_note = true;
  485. break;
  486. }
  487. }
  488. if (has_note) {
  489. max = c + 1;
  490. }
  491. }
  492. }
  493. return max;
  494. }
  495. void CPSong::separate_in_one_sample_instruments(int p_instrument) {
  496. CP_ERR_COND(!variables.use_instruments);
  497. CP_FAIL_INDEX(p_instrument, MAX_INSTRUMENTS);
  498. int remapped_count = 0;
  499. signed char remap[MAX_SAMPLES];
  500. for (int i = 0; i < MAX_SAMPLES; i++) {
  501. remap[i] = -1;
  502. }
  503. /* Find remaps */
  504. CPInstrument *ins = get_instrument(p_instrument);
  505. for (int i = 0; i < CPNote::NOTES; i++) {
  506. int sn = ins->get_sample_number(i);
  507. // check for unusable sample
  508. if (sn < 0 || sn >= MAX_SAMPLES || get_sample(sn)->get_sample_data().is_null())
  509. continue;
  510. printf("sample %i\n", sn);
  511. if (remap[sn] != -1) {
  512. printf("already mapped to %i\n", remap[sn]);
  513. continue;
  514. }
  515. printf("isn't remapped\n");
  516. // find remap
  517. for (int j = 0; j < MAX_INSTRUMENTS; j++) {
  518. if (!get_instrument(j)->is_empty())
  519. continue;
  520. printf("map to %i\n", j);
  521. //copy
  522. *get_instrument(j) = *ins;
  523. // assign samples
  524. for (int k = 0; k < CPNote::NOTES; k++) {
  525. get_instrument(j)->set_note_number(k, k);
  526. get_instrument(j)->set_sample_number(k, sn);
  527. }
  528. remap[sn] = j;
  529. remapped_count++;
  530. break;
  531. }
  532. CP_ERR_COND(remap[sn] == -1); // no more free instruments
  533. }
  534. printf("remapped %i\n", remapped_count);
  535. if (remapped_count < 2) {
  536. //undo if only one is remapped
  537. for (int i = 0; i < MAX_SAMPLES; i++) {
  538. if (remap[i] != -1) {
  539. get_instrument(remap[i])->reset();
  540. }
  541. }
  542. return;
  543. }
  544. /* remap all song */
  545. for (int p = 0; p < CPSong::MAX_PATTERNS; p++) {
  546. CPPattern *pat = get_pattern(p);
  547. if (pat->is_empty())
  548. continue;
  549. for (int c = 0; c < CPPattern::WIDTH; c++) {
  550. for (int r = 0; r < pat->get_length(); r++) {
  551. CPNote n = pat->get_note(c, r);
  552. if (n.note < CPNote::NOTES && n.instrument == p_instrument) {
  553. int sn = ins->get_sample_number(n.note);
  554. if (remap[sn] == -1)
  555. pat->set_note(c, r, CPNote());
  556. else {
  557. n.instrument = remap[sn];
  558. pat->set_note(c, r, n);
  559. }
  560. }
  561. }
  562. }
  563. }
  564. ins->reset();
  565. }
  566. CPSong::CPSong() {
  567. reset();
  568. }
  569. CPSong::~CPSong() {
  570. }
  571. int get_song_next_order_idx(CPSong *p_song, int p_order_idx) {
  572. int baseorder, order_counter;
  573. order_counter = -1;
  574. baseorder = p_order_idx;
  575. do {
  576. baseorder++;
  577. if (baseorder > (CPSong::MAX_ORDERS - 1)) baseorder = 0;
  578. order_counter++;
  579. } while ((p_song->get_order(baseorder) >= (CPSong::MAX_PATTERNS)) && (order_counter < CPSong::MAX_ORDERS));
  580. if (order_counter == CPSong::MAX_ORDERS) {
  581. return -1;
  582. } else {
  583. return baseorder;
  584. }
  585. }