1 2 /* 3 * The Real SoundTracker - General support routines 4 * 5 * Copyright (C) 1998-2019 Michael Krause 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 22 #include <pthread.h> 23 24 #include <stdlib.h> 25 #include <string.h> 26 27 #include <glib.h> 28 29 #include "st-subs.h" 30 #include "xm.h" 31 32 int st_init_pattern_channels(XMPattern* p, 33 unsigned length, 34 int num_channels) 35 { 36 int i; 37 38 p->length = p->alloc_length = length; 39 for (i = 0; i < num_channels; i++) { 40 if (!(p->channels[i] = calloc(1, length * sizeof(XMNote)))) { 41 st_free_pattern_channels(p); 42 return 0; 43 } 44 } 45 46 return 1; 47 } 48 49 void st_free_pattern_channels(XMPattern* pat) 50 { 51 int i; 52 53 for (i = 0; i < 32; i++) { 54 free(pat->channels[i]); 55 pat->channels[i] = NULL; 56 } 57 } 58 59 void st_free_all_pattern_channels(XM* xm) 60 { 61 int i; 62 63 for (i = 0; i < 256; i++) 64 st_free_pattern_channels(&xm->patterns[i]); 65 } 66 67 int st_copy_pattern(XMPattern* dst, 68 XMPattern* src) 69 { 70 XMNote* oldchans[32]; 71 int i; 72 73 for (i = 0; i < 32; i++) { 74 oldchans[i] = dst->channels[i]; 75 if (src->channels[i]) { 76 if (!(dst->channels[i] = st_dup_track(src->channels[i], src->length))) { 77 // Out of memory, restore previous pattern, return error 78 for (; i >= 0; i--) { 79 free(dst->channels[i]); 80 dst->channels[i] = oldchans[i]; 81 } 82 return 0; 83 } 84 } else { 85 dst->channels[i] = NULL; 86 } 87 } 88 89 for (i = 0; i < 32; i++) 90 free(oldchans[i]); 91 92 dst->length = dst->alloc_length = src->length; 93 94 return 1; 95 } 96 97 XMPattern* 98 st_dup_pattern(XMPattern* p) 99 { 100 XMPattern* r; 101 102 r = g_new0(XMPattern, 1); 103 if (!r) 104 return NULL; 105 106 if (!st_copy_pattern(r, p)) { 107 g_free(r); 108 return NULL; 109 } 110 111 return r; 112 } 113 114 XMNote* 115 st_dup_track(XMNote* n, 116 int length) 117 { 118 XMNote* r; 119 120 if (!n) 121 return NULL; 122 123 r = malloc(length * sizeof(XMNote)); 124 if (r) { 125 memcpy(r, n, length * sizeof(XMNote)); 126 } 127 128 return r; 129 } 130 131 /* Duplicate part of a track, wrap-around at end is handled */ 132 XMNote* 133 st_dup_track_wrap(XMNote* n, 134 int tracklength, 135 int copystart, 136 int copylength) 137 { 138 XMNote* r; 139 140 if (!n || copylength > tracklength || copystart >= tracklength) 141 return NULL; 142 143 if (copylength > tracklength - copystart) { 144 r = malloc(copylength * sizeof(XMNote)); 145 if (r) { 146 memcpy(r, n + copystart, (tracklength - copystart) * sizeof(XMNote)); 147 memcpy(r + tracklength - copystart, n, (copylength - (tracklength - copystart)) * sizeof(XMNote)); 148 } 149 } else { 150 r = st_dup_track(n + copystart, copylength); 151 } 152 153 return r; 154 } 155 156 void st_clear_track(XMNote* n, 157 int length) 158 { 159 if (!n) 160 return; 161 162 memset(n, 0, length * sizeof(*n)); 163 } 164 165 /* Clear part of a track, wrap-around at end is handled */ 166 void st_clear_track_wrap(XMNote* n, 167 int tracklength, 168 int clearstart, 169 int clearlength) 170 { 171 if (!n || clearlength > tracklength || clearstart >= tracklength) 172 return; 173 174 if (clearlength > tracklength - clearstart) { 175 st_clear_track(n + clearstart, tracklength - clearstart); 176 st_clear_track(n, clearlength - (tracklength - clearstart)); 177 } else { 178 st_clear_track(n + clearstart, clearlength); 179 } 180 } 181 182 void st_paste_track_into_track_wrap(XMNote* from, 183 XMNote* to, 184 int tolength, 185 int insertstart, 186 int fromlength) 187 { 188 if (!from || !to || tolength < fromlength || insertstart >= tolength) 189 return; 190 191 if (fromlength > tolength - insertstart) { 192 memcpy(to + insertstart, from, (tolength - insertstart) * sizeof(XMNote)); 193 memcpy(to, from + tolength - insertstart, (fromlength - (tolength - insertstart)) * sizeof(XMNote)); 194 } else { 195 memcpy(to + insertstart, from, fromlength * sizeof(XMNote)); 196 } 197 } 198 199 void st_clear_pattern(XMPattern* p) 200 { 201 int i; 202 203 for (i = 0; i < 32; i++) { 204 st_clear_track(p->channels[i], p->alloc_length); 205 } 206 } 207 208 void st_pattern_delete_track(XMPattern* p, 209 int t) 210 { 211 int i; 212 XMNote* a; 213 214 a = p->channels[t]; 215 g_assert(a != NULL); 216 217 for (i = t; i < 31 && p->channels[i + 1] != NULL; i++) { 218 p->channels[i] = p->channels[i + 1]; 219 } 220 221 p->channels[i] = a; 222 st_clear_track(a, p->alloc_length); 223 } 224 225 void st_pattern_insert_track(XMPattern* p, 226 int t) 227 { 228 int i; 229 XMNote* a; 230 231 a = p->channels[31]; 232 233 for (i = 31; i > t; i--) { 234 p->channels[i] = p->channels[i - 1]; 235 } 236 237 if (!a) { 238 if (!(a = calloc(1, p->alloc_length * sizeof(XMNote)))) { 239 g_assert_not_reached(); 240 } 241 } 242 243 p->channels[t] = a; 244 st_clear_track(a, p->alloc_length); 245 } 246 247 gboolean 248 st_instrument_used_in_song(XM* xm, 249 int instr) 250 { 251 int i, j, k; 252 XMPattern* p; 253 XMNote* c; 254 255 for (i = 0; i < xm->song_length; i++) { 256 p = &xm->patterns[(int)xm->pattern_order_table[i]]; 257 for (j = 0; j < xm->num_channels; j++) { 258 c = p->channels[j]; 259 for (k = 0; k < p->length; k++) { 260 if (c[k].instrument == instr) 261 return TRUE; 262 } 263 } 264 } 265 266 return FALSE; 267 } 268 269 int st_instrument_num_samples(STInstrument* instr) 270 { 271 int i, n; 272 273 for (i = 0, n = 0; i < ST_NUM_SAMPLES(instr); i++) { 274 if (instr->samples[i].sample.length != 0) 275 n++; 276 } 277 return n; 278 } 279 280 int st_instrument_num_save_samples(STInstrument* instr) 281 { 282 int i, n; 283 284 for (i = 0, n = 0; i < ST_NUM_SAMPLES(instr); i++) { 285 if (instr->samples[i].sample.length != 0 || instr->samples[i].utf_name[0] != 0) 286 n = i + 1; 287 } 288 return n; 289 } 290 291 gsize 292 st_get_instrument_size(STInstrument* instr) 293 { 294 gint i; 295 gsize s; 296 297 for (i = 0, s = 0; i < ST_NUM_SAMPLES(instr); i++) 298 /* Length in samples which are internally in 2-bytes format */ 299 s += instr->samples[i].sample.length * sizeof(instr->samples[i].sample.data[0]); 300 301 return s + sizeof(STInstrument); 302 } 303 304 int st_num_save_instruments(XM* xm) 305 { 306 int i, n; 307 308 for (i = 0, n = 0; i < ST_NUM_INSTRUMENTS(xm); i++) { 309 if (st_instrument_num_save_samples(&xm->instruments[i]) != 0 || xm->instruments[i].utf_name[0] != 0) 310 n = i + 1; 311 } 312 return n; 313 } 314 315 int st_num_save_patterns(XM* xm) 316 { 317 int i, n; 318 319 for (i = 0, n = 0; i < 256; i++) { 320 if (!st_is_empty_pattern(&xm->patterns[i])) 321 n = i; 322 } 323 324 return n + 1; 325 } 326 327 void st_copy_instrument(STInstrument* src, STInstrument* dest) 328 { 329 int i; 330 guint32 length; 331 GMutex lock[ST_NUM_SAMPLES(src)]; 332 333 st_clean_instrument(dest, NULL); 334 335 for (i = 0; i < ST_NUM_SAMPLES(dest); i++) 336 lock[i] = dest->samples[i].sample.lock; /* Preserve GMutex'es from modification */ 337 memcpy(dest, src, sizeof(STInstrument)); 338 for (i = 0; i < ST_NUM_SAMPLES(dest); i++) { 339 if ((length = dest->samples[i].sample.length * sizeof(dest->samples[i].sample.data[0]))) { 340 dest->samples[i].sample.data = malloc(length); 341 memcpy(dest->samples[i].sample.data, src->samples[i].sample.data, length); 342 } 343 dest->samples[i].sample.lock = lock[i]; 344 } 345 } 346 347 void st_clean_instrument_full(STInstrument* instr, 348 const char* name, const gboolean modify_name) 349 { 350 int i; 351 352 for (i = 0; i < ST_NUM_SAMPLES(instr); i++) 353 st_clean_sample_full(&instr->samples[i], NULL, NULL, modify_name); 354 355 if (modify_name) { 356 if (!name) { 357 memset(instr->name, 0, sizeof(instr->name)); 358 memset(instr->utf_name, 0, sizeof(instr->utf_name)); 359 instr->needs_conversion = FALSE; 360 } else { 361 g_utf8_strncpy(instr->utf_name, name, sizeof(instr->name) - 1); 362 instr->needs_conversion = TRUE; 363 } 364 } 365 memset(instr->samplemap, 0, sizeof(instr->samplemap)); 366 memset(&instr->vol_env, 0, sizeof(instr->vol_env)); 367 memset(&instr->pan_env, 0, sizeof(instr->pan_env)); 368 instr->vol_env.num_points = 1; 369 instr->vol_env.points[0].val = 64; 370 instr->pan_env.num_points = 1; 371 instr->pan_env.points[0].val = 32; 372 } 373 374 void st_set_sample_name(STSample* s, 375 const char* name) 376 { 377 g_utf8_strncpy(s->utf_name, name, sizeof(s->name) - 1); 378 s->needs_conversion = TRUE; 379 } 380 381 void st_clean_sample_full(STSample* s, 382 const char* utf_name, const char* name, 383 const gboolean clear_name) 384 { 385 free(s->sample.data); 386 s->sample.data = NULL; 387 s->sample.looptype = 0; 388 s->sample.length = 0; 389 s->sample.loopend = 1; 390 s->sample.loopstart = 0; 391 s->volume = 0; 392 s->finetune = 0; 393 s->panning = 0; 394 s->relnote = 0; 395 s->treat_as_8bit = 0; 396 397 if (clear_name) { 398 if (utf_name) { 399 g_utf8_strncpy(s->utf_name, utf_name, sizeof(s->name) - 1); 400 if (!name) 401 s->needs_conversion = TRUE; 402 else { 403 strncpy(s->name, name, sizeof(s->name) - 1); 404 s->needs_conversion = FALSE; 405 } 406 } else { 407 memset(s->utf_name, 0, sizeof(s->utf_name)); 408 memset(s->name, 0, sizeof(s->name)); 409 s->needs_conversion = FALSE; 410 } 411 } 412 } 413 414 void st_copy_sample(STSample* src_smp, STSample* dest_smp) 415 { 416 guint32 length; 417 GMutex lock = dest_smp->sample.lock; 418 419 if (dest_smp->sample.data) 420 g_free(dest_smp->sample.data); 421 memcpy(dest_smp, src_smp, sizeof(STSample)); 422 dest_smp->sample.lock = lock; 423 length = sizeof(dest_smp->sample.data[0]) * dest_smp->sample.length; 424 dest_smp->sample.data = malloc(length); 425 memcpy(dest_smp->sample.data, src_smp->sample.data, length); 426 } 427 428 void st_clean_song(XM* xm) 429 { 430 int i; 431 432 st_free_all_pattern_channels(xm); 433 434 xm->song_length = 1; 435 xm->restart_position = 0; 436 xm->num_channels = 8; 437 xm->tempo = 6; 438 xm->bpm = 125; 439 xm->flags = 0; 440 memset(xm->pattern_order_table, 0, sizeof(xm->pattern_order_table)); 441 442 for (i = 0; i < 256; i++) 443 st_init_pattern_channels(&xm->patterns[i], 64, xm->num_channels); 444 } 445 446 void st_set_num_channels(XM* xm, 447 int n) 448 { 449 int i, j; 450 XMPattern* pat; 451 452 for (i = 0; i < ST_NUM_PATTERNS(xm); i++) { 453 pat = &xm->patterns[i]; 454 for (j = 0; j < n; j++) { 455 if (!pat->channels[j]) { 456 pat->channels[j] = calloc(1, sizeof(XMNote) * pat->alloc_length); 457 } 458 } 459 } 460 461 xm->num_channels = n; 462 } 463 464 void st_set_pattern_length(XMPattern* pat, 465 int l) 466 { 467 int i; 468 XMNote* n; 469 470 if (l > pat->alloc_length) { 471 for (i = 0; i < 32 && pat->channels[i] != NULL; i++) { 472 n = calloc(1, sizeof(XMNote) * l); 473 memcpy(n, pat->channels[i], sizeof(XMNote) * pat->length); 474 free(pat->channels[i]); 475 pat->channels[i] = n; 476 } 477 pat->alloc_length = l; 478 } 479 480 pat->length = l; 481 } 482 483 void st_sample_fix_loop(STSample* sts) 484 { 485 st_mixer_sample_info* s = &sts->sample; 486 487 if (s->loopend > s->length) 488 s->loopend = s->length; 489 else if (!s->loopend) 490 s->loopend = 1; 491 if (s->loopstart >= s->loopend) 492 s->loopstart = s->loopend - 1; 493 } 494 495 int st_find_first_unused_and_empty_pattern(XM* xm) 496 { 497 int i; 498 499 for (i = 0; i < ST_NUM_PATTERNS(xm); i++) { 500 if (!st_is_pattern_used_in_song(xm, i) && st_is_empty_pattern(&xm->patterns[i])) { 501 return i; 502 } 503 } 504 505 return -1; 506 } 507 508 gboolean 509 st_is_empty_pattern(XMPattern* p) 510 { 511 int i; 512 513 for (i = 0; i < 32; i++) { 514 if (p->channels[i]) { 515 if (!st_is_empty_track(p->channels[i], p->length)) { 516 return 0; 517 } 518 } 519 } 520 521 return 1; 522 } 523 524 gboolean 525 st_is_empty_track(XMNote* notes, 526 int length) 527 { 528 for (; length > 0; length--, notes++) { 529 if (notes->note != 0 || notes->instrument != 0 || notes->volume != 0 530 || notes->fxtype != 0 || notes->fxparam != 0) { 531 return 0; 532 } 533 } 534 535 return 1; 536 } 537 538 gboolean 539 st_is_pattern_used_in_song(XM* xm, 540 int patnum) 541 { 542 int i; 543 544 for (i = 0; i < xm->song_length; i++) 545 if (xm->pattern_order_table[i] == patnum) 546 return 1; 547 548 return 0; 549 } 550 551 void st_exchange_patterns(XM* xm, 552 int p1, 553 int p2) 554 { 555 XMPattern tmp; 556 int i; 557 558 memcpy(&tmp, &xm->patterns[p1], sizeof(XMPattern)); 559 memcpy(&xm->patterns[p1], &xm->patterns[p2], sizeof(XMPattern)); 560 memcpy(&xm->patterns[p2], &tmp, sizeof(XMPattern)); 561 562 for (i = 0; i < xm->song_length; i++) { 563 if (xm->pattern_order_table[i] == p1) 564 xm->pattern_order_table[i] = p2; 565 else if (xm->pattern_order_table[i] == p2) 566 xm->pattern_order_table[i] = p1; 567 } 568 } 569 570 gboolean 571 st_check_if_odd_are_not_empty(XMPattern* p) 572 { 573 int i, j; 574 575 for (i = 0; i < 32 && p->channels[i]; i++) 576 for (j = 1; j < p->length; j += 2) 577 if ((p->channels[i][j].note && p->channels[i][j].instrument) || (p->channels[i][j].volume > 15) || p->channels[i][j].fxtype || p->channels[i][j].fxparam) 578 return TRUE; 579 580 return FALSE; 581 } 582 583 void st_shrink_pattern(XMPattern* p) 584 { 585 int i, j, length = p->length; 586 587 for (i = 0; i < 32 && p->channels[i]; i++) { 588 for (j = 1; j <= (length - 1) / 2; j++) 589 memcpy(&p->channels[i][j], &p->channels[i][2 * j], sizeof(XMNote)); 590 for (; j < p->alloc_length; j++) { /* clear the rest of the pattern */ 591 p->channels[i][j].note = 0; 592 p->channels[i][j].instrument = 0; 593 p->channels[i][j].volume = 0; 594 p->channels[i][j].fxtype = 0; 595 p->channels[i][j].fxparam = 0; 596 } 597 } 598 599 st_set_pattern_length(p, (length - 1) / 2 + 1); 600 } 601 602 void st_expand_pattern(XMPattern* p) 603 { 604 int i, j, length = MIN(p->length * 2, 256); 605 606 st_set_pattern_length(p, length); 607 608 for (i = 0; i < 32 && p->channels[i]; i++) { 609 for (j = length / 2 - 1; j >= 0; j--) { 610 /* copy to even positions and clear odd */ 611 memcpy(&p->channels[i][2 * j], &p->channels[i][j], sizeof(XMNote)); 612 p->channels[i][2 * j + 1].note = 0; 613 p->channels[i][2 * j + 1].instrument = 0; 614 p->channels[i][2 * j + 1].volume = 0; 615 p->channels[i][2 * j + 1].fxtype = 0; 616 p->channels[i][2 * j + 1].fxparam = 0; 617 } 618 } 619 } 620 621 void st_convert_sample(void* src, 622 void* dst, 623 int srcformat, 624 int dstformat, 625 int count) 626 { 627 gint16* d16; 628 gint8* d8; 629 630 if (srcformat == dstformat) { 631 memcpy(dst, src, count * (srcformat / 8)); 632 } else { 633 if (dstformat == 16) { 634 /* convert to 16 bit */ 635 d16 = dst; 636 d8 = src; 637 while (count--) 638 *d16++ = (*d8++ << 8); 639 } else { 640 /* convert to 8 bit */ 641 d8 = dst; 642 d16 = src; 643 while (count--) 644 *d8++ = (*d16++ >> 8); 645 } 646 } 647 } 648 649 void st_sample_8bit_signed_unsigned(gint8* data, 650 int count) 651 { 652 while (count) { 653 *data++ += 128; 654 count--; 655 } 656 } 657 658 void st_sample_16bit_signed_unsigned(gint16* data, 659 int count) 660 { 661 while (count) { 662 *data++ += 32768; 663 count--; 664 } 665 } 666