1 /* Author: Romain "Artefact2" Dalmaso <artefact2@gmail.com> */ 2 3 /* This program is free software. It comes without any warranty, to the 4 * extent permitted by applicable law. You can redistribute it and/or 5 * modify it under the terms of the Do What The Fuck You Want To Public 6 * License, Version 2, as published by Sam Hocevar. See 7 * http://sam.zoy.org/wtfpl/COPYING for more details. */ 8 module audioformats.libxm; 9 10 import core.stdc.config: c_ulong; 11 import core.stdc.stdlib: malloc, free; 12 import core.stdc.string: memcpy, memcmp, memset; 13 14 import dplug.core.math; 15 16 nothrow: 17 @nogc: 18 19 private alias int8_t = byte; 20 private alias int16_t = short; 21 private alias int32_t = int; 22 private alias uint8_t = ubyte; 23 private alias uint16_t = ushort; 24 private alias uint32_t = uint; 25 private alias uint64_t = ulong; 26 27 // xm_internal.h 28 29 version(BigEndian) 30 { 31 static assert(false, "Big endian platforms are not yet supported, sorry"); 32 } 33 34 /* ----- XM constants ----- */ 35 36 enum SAMPLE_NAME_LENGTH = 22; 37 enum INSTRUMENT_HEADER_LENGTH = 263; 38 enum INSTRUMENT_NAME_LENGTH = 22; 39 enum MODULE_NAME_LENGTH = 20; 40 enum TRACKER_NAME_LENGTH = 20; 41 enum PATTERN_ORDER_TABLE_LENGTH = 256; 42 enum NUM_NOTES = 96; 43 enum NUM_ENVELOPE_POINTS = 12; 44 enum MAX_NUM_ROWS = 256; 45 46 47 // Options 48 version = XM_RAMPING; // sounds better to me when on 49 //version = XM_STRINGS; 50 enum XM_DEFENSIVE = true; 51 enum XM_LINEAR_INTERPOLATION = false; // sounds better/digital to me when off 52 enum XM_DEBUG = false; 53 54 version(XM_RAMPING) 55 { 56 enum XM_SAMPLE_RAMPING_POINTS = 0x20; 57 } 58 59 /* ----- Data types ----- */ 60 61 alias xm_waveform_type_t = int; 62 enum : xm_waveform_type_t { 63 XM_SINE_WAVEFORM = 0, 64 XM_RAMP_DOWN_WAVEFORM = 1, 65 XM_SQUARE_WAVEFORM = 2, 66 XM_RANDOM_WAVEFORM = 3, 67 XM_RAMP_UP_WAVEFORM = 4, 68 } 69 70 alias xm_loop_type_t = int; 71 enum : xm_loop_type_t 72 { 73 XM_NO_LOOP, 74 XM_FORWARD_LOOP, 75 XM_PING_PONG_LOOP, 76 } 77 78 alias xm_frequency_type_t = int; 79 enum : xm_frequency_type_t 80 { 81 XM_LINEAR_FREQUENCIES, 82 XM_AMIGA_FREQUENCIES, 83 } 84 85 struct xm_envelope_point_t 86 { 87 uint16_t frame; 88 uint16_t value; 89 } 90 91 struct xm_envelope_t 92 { 93 xm_envelope_point_t[NUM_ENVELOPE_POINTS] points; 94 uint8_t num_points; 95 uint8_t sustain_point; 96 uint8_t loop_start_point; 97 uint8_t loop_end_point; 98 bool enabled; 99 bool sustain_enabled; 100 bool loop_enabled; 101 } 102 103 struct xm_sample_t 104 { 105 version(XM_STRINGS) 106 { 107 char[SAMPLE_NAME_LENGTH + 1] name; 108 } 109 110 uint8_t bits; /* Either 8 or 16 */ 111 112 uint32_t length; 113 uint32_t loop_start; 114 uint32_t loop_length; 115 uint32_t loop_end; 116 float volume; 117 int8_t finetune; 118 xm_loop_type_t loop_type; 119 float panning; 120 int8_t relative_note; 121 uint64_t latest_trigger; 122 123 union { 124 int8_t* data8; 125 int16_t* data16; 126 }; 127 } 128 129 struct xm_instrument_t 130 { 131 version(XM_STRINGS) 132 { 133 char[INSTRUMENT_NAME_LENGTH + 1] name; 134 } 135 uint16_t num_samples; 136 uint8_t[NUM_NOTES] sample_of_notes; 137 xm_envelope_t volume_envelope; 138 xm_envelope_t panning_envelope; 139 xm_waveform_type_t vibrato_type; 140 uint8_t vibrato_sweep; 141 uint8_t vibrato_depth; 142 uint8_t vibrato_rate; 143 uint16_t volume_fadeout; 144 uint64_t latest_trigger; 145 bool muted; 146 147 xm_sample_t* samples; 148 } 149 150 struct xm_pattern_slot_t 151 { 152 uint8_t note; /* 1-96, 97 = Key Off note */ 153 uint8_t instrument; /* 1-128 */ 154 uint8_t volume_column; 155 uint8_t effect_type; 156 uint8_t effect_param; 157 158 nothrow: 159 @nogc: 160 161 bool HAS_TONE_PORTAMENTO() 162 { 163 return effect_type == 3 || effect_type == 5 || ((volume_column >> 4) == 0xF); 164 } 165 166 bool HAS_ARPEGGIO() 167 { 168 return effect_param != 0; 169 } 170 171 bool HAS_VIBRATO() 172 { 173 return effect_type == 4 || effect_type == 6 || (volume_column >> 4) == 0xB; 174 } 175 } 176 177 struct xm_pattern_t 178 { 179 uint16_t num_rows; 180 xm_pattern_slot_t* slots; /* Array of size num_rows * num_channels */ 181 } 182 183 struct xm_module_t 184 { 185 version(XM_STRINGS) 186 { 187 char[MODULE_NAME_LENGTH + 1] name; 188 char[TRACKER_NAME_LENGTH + 1] trackername; 189 } 190 191 uint16_t length; 192 uint16_t restart_position; 193 uint16_t num_channels; 194 uint16_t num_patterns; 195 uint16_t num_instruments; 196 xm_frequency_type_t frequency_type; 197 uint8_t[PATTERN_ORDER_TABLE_LENGTH] pattern_table; 198 199 xm_pattern_t* patterns; 200 xm_instrument_t* instruments; /* Instrument 1 has index 0, 201 * instrument 2 has index 1, etc. */ 202 } 203 204 struct xm_channel_context_t 205 { 206 float note; 207 float orig_note; /* The original note before effect modifications, as read in the pattern. */ 208 xm_instrument_t* instrument; /* Could be null */ 209 xm_sample_t* sample; /* Could be null */ 210 xm_pattern_slot_t* current; 211 212 float sample_position; 213 float period; 214 float frequency; 215 float step; 216 bool ping; /* For ping-pong samples: true is -., false is <-- */ 217 218 float volume; /* Ideally between 0 (muted) and 1 (loudest) */ 219 float panning; /* Between 0 (left) and 1 (right); 0.5 is centered */ 220 221 uint16_t autovibrato_ticks; 222 223 bool sustained; 224 float fadeout_volume; 225 float volume_envelope_volume; 226 float panning_envelope_panning; 227 uint16_t volume_envelope_frame_count; 228 uint16_t panning_envelope_frame_count; 229 230 float autovibrato_note_offset; 231 232 bool arp_in_progress; 233 uint8_t arp_note_offset; 234 uint8_t volume_slide_param; 235 uint8_t fine_volume_slide_param; 236 uint8_t global_volume_slide_param; 237 uint8_t panning_slide_param; 238 uint8_t portamento_up_param; 239 uint8_t portamento_down_param; 240 uint8_t fine_portamento_up_param; 241 uint8_t fine_portamento_down_param; 242 uint8_t extra_fine_portamento_up_param; 243 uint8_t extra_fine_portamento_down_param; 244 uint8_t tone_portamento_param; 245 float tone_portamento_target_period; 246 uint8_t multi_retrig_param; 247 uint8_t note_delay_param; 248 uint8_t pattern_loop_origin; /* Where to restart a E6y loop */ 249 uint8_t pattern_loop_count; /* How many loop passes have been done */ 250 bool vibrato_in_progress; 251 xm_waveform_type_t vibrato_waveform; 252 bool vibrato_waveform_retrigger; /* True if a new note retriggers the waveform */ 253 uint8_t vibrato_param; 254 uint16_t vibrato_ticks; /* Position in the waveform */ 255 float vibrato_note_offset; 256 xm_waveform_type_t tremolo_waveform; 257 bool tremolo_waveform_retrigger; 258 uint8_t tremolo_param; 259 uint8_t tremolo_ticks; 260 float tremolo_volume; 261 uint8_t tremor_param; 262 bool tremor_on; 263 264 uint64_t latest_trigger; 265 bool muted; 266 267 version(XM_RAMPING) 268 { 269 /* These values are updated at the end of each tick, to save 270 * a couple of float operations on every generated sample. */ 271 float[2] target_volume; 272 273 c_ulong frame_count; 274 float[XM_SAMPLE_RAMPING_POINTS] end_of_previous_sample; 275 } 276 277 float[2] actual_volume; 278 } 279 280 struct xm_context_t 281 { 282 size_t ctx_size; /* Must be first, see xm_create_context_from_libxmize() */ 283 xm_module_t module_; 284 uint32_t rate; 285 286 uint16_t tempo; 287 uint16_t bpm; 288 float global_volume; 289 float amplification; 290 291 version(XM_RAMPING) 292 { 293 /* How much is a channel final volume allowed to change per 294 * sample; this is used to avoid abrubt volume changes which 295 * manifest as "clicks" in the generated sound. */ 296 float volume_ramp; 297 } 298 299 uint next_rand; 300 301 uint8_t current_table_index; 302 uint8_t current_row; 303 uint16_t current_tick; /* Can go below 255, with high tempo and a pattern delay */ 304 float remaining_samples_in_tick; 305 uint64_t generated_samples; 306 307 bool position_jump; 308 bool pattern_break; 309 uint8_t jump_dest; 310 uint8_t jump_row; 311 312 313 /* Extra ticks to be played before going to the next row - 314 * Used for EEy effect */ 315 uint16_t extra_ticks; 316 317 uint8_t* row_loop_count; /* Array of size MAX_NUM_ROWS * module_length */ 318 uint8_t loop_count; 319 uint8_t max_loop_count; 320 321 xm_channel_context_t* channels; 322 } 323 324 // xm.c 325 326 /* .xm files are little-endian. */ 327 328 /* Bounded reader macros. 329 * If we attempt to read the buffer out-of-bounds, pretend that the buffer is 330 * infinitely padded with zeroes. 331 */ 332 /* 333 #define READ_U8_BOUND(offset, bound) (((offset) < bound) ? (*(uint8_t*)(moddata + (offset))) : 0) 334 #define READ_U16_BOUND(offset, bound) ((uint16_t)READ_U8(offset) | ((uint16_t)READ_U8((offset) + 1) << 8)) 335 #define READ_U32_BOUND(offset, bound) ((uint32_t)READ_U16(offset) | ((uint32_t)READ_U16((offset) + 2) << 16)) 336 #define READ_MEMCPY_BOUND(ptr, offset, length, bound) memcpy_pad(ptr, length, moddata, bound, offset) 337 338 #define READ_U8(offset) READ_U8_BOUND(offset, moddata_length) 339 #define READ_U16(offset) READ_U16_BOUND(offset, moddata_length) 340 #define READ_U32(offset) READ_U32_BOUND(offset, moddata_length) 341 #define READ_MEMCPY(ptr, offset, length) READ_MEMCPY_BOUND(ptr, offset, length, moddata_length) 342 */ 343 void memcpy_pad(void* dst, size_t dst_len, const(void)* src, size_t src_len, size_t offset) 344 { 345 uint8_t* dst_c = cast(uint8_t*)dst; 346 const(uint8_t)* src_c = cast(const(uint8_t)*)src; 347 348 /* how many bytes can be copied without overrunning `src` */ 349 size_t copy_bytes = (src_len >= offset) ? (src_len - offset) : 0; 350 copy_bytes = copy_bytes > dst_len ? dst_len : copy_bytes; 351 352 memcpy(dst_c, src_c + offset, copy_bytes); 353 /* padded bytes */ 354 memset(dst_c + copy_bytes, 0, dst_len - copy_bytes); 355 } 356 357 /** Check the module data for errors/inconsistencies. 358 * 359 * @returns 0 if everything looks OK. Module should be safe to load. 360 */ 361 int xm_check_sanity_preload(const(char)* module_, size_t module_length) 362 { 363 if(module_length < 60) { 364 return 4; 365 } 366 367 if(memcmp("Extended Module: ".ptr, module_, 17) != 0) { 368 return 1; 369 } 370 371 if(module_[37] != 0x1A) { 372 return 2; 373 } 374 375 if(module_[59] != 0x01 || module_[58] != 0x04) { 376 /* Not XM 1.04 */ 377 return 3; 378 } 379 380 return 0; 381 } 382 383 /** Check a loaded module for errors/inconsistencies. 384 * 385 * @returns 0 if everything looks OK. 386 */ 387 388 int xm_check_sanity_postload(xm_context_t* ctx) 389 { 390 /* @todo: plenty of stuff to do here */ 391 392 /* Check the POT */ 393 for(uint8_t i = 0; i < ctx.module_.length; ++i) { 394 if(ctx.module_.pattern_table[i] >= ctx.module_.num_patterns) { 395 if(i+1 == ctx.module_.length && ctx.module_.length > 1) { 396 /* Cheap fix */ 397 --ctx.module_.length; 398 // DEBUG("trimming invalid POT at pos %X", i); 399 } 400 else 401 { 402 import core.stdc.stdio; 403 printf("module has invalid POT, pos %X references nonexistent pattern %X", i, ctx.module_.pattern_table[i]); 404 405 return 1; 406 } 407 } 408 } 409 410 return 0; 411 } 412 413 /** Get the number of bytes needed to store the module data in a 414 * dynamically allocated blank context. 415 * 416 * Things that are dynamically allocated: 417 * - sample data 418 * - sample structures in instruments 419 * - pattern data 420 * - row loop count arrays 421 * - pattern structures in module 422 * - instrument structures in module 423 * - channel contexts 424 * - context structure itself 425 426 * @returns 0 if everything looks OK. 427 */ 428 size_t xm_get_memory_needed_for_context(const char* moddata, size_t moddata_length) 429 { 430 size_t memory_needed = 0; 431 size_t offset = 60; /* Skip the first header */ 432 uint16_t num_channels; 433 uint16_t num_patterns; 434 uint16_t num_instruments; 435 436 /* Read the module header */ 437 438 ubyte READ_U8_BOUND(size_t offset, size_t bound) 439 { 440 return (offset < bound) ? *cast(uint8_t*)(moddata + offset) : 0; 441 } 442 443 ubyte READ_U8(size_t offset) 444 { 445 return READ_U8_BOUND(offset, moddata_length); 446 } 447 448 ushort READ_U16_BOUND(size_t offset, size_t bound) 449 { 450 return (cast(uint16_t)READ_U8(offset) | (cast(uint16_t)READ_U8((offset) + 1) << 8)); 451 } 452 453 ushort READ_U16(size_t offset) 454 { 455 return READ_U16_BOUND(offset, moddata_length); 456 } 457 458 uint READ_U32_BOUND(size_t offset, size_t bound) 459 { 460 return (cast(uint32_t)READ_U16(offset) | (cast(uint32_t)READ_U16((offset) + 2) << 16)); 461 } 462 463 uint READ_U32(size_t offset) 464 { 465 return READ_U32_BOUND(offset, moddata_length); 466 } 467 468 void READ_MEMCPY_BOUND(void* ptr, size_t offset, size_t length, size_t bound) 469 { 470 memcpy_pad(ptr, length, moddata, bound, offset); 471 } 472 473 void READ_MEMCPY(void* ptr, size_t ffset, size_t length) 474 { 475 return READ_MEMCPY_BOUND(ptr, offset, length, moddata_length); 476 } 477 478 479 num_channels = READ_U16(offset + 8); 480 num_channels = READ_U16(offset + 8); 481 482 num_patterns = READ_U16(offset + 10); 483 memory_needed += num_patterns * xm_pattern_t.sizeof; 484 485 num_instruments = READ_U16(offset + 12); 486 memory_needed += num_instruments * xm_instrument_t.sizeof; 487 488 memory_needed += MAX_NUM_ROWS * READ_U16(offset + 4) * uint8_t.sizeof; /* Module length */ 489 490 /* Header size */ 491 offset += READ_U32(offset); 492 493 /* Read pattern headers */ 494 for(uint16_t i = 0; i < num_patterns; ++i) { 495 uint16_t num_rows; 496 497 num_rows = READ_U16(offset + 5); 498 memory_needed += num_rows * num_channels * xm_pattern_slot_t.sizeof; 499 500 /* Pattern header length + packed pattern data size */ 501 offset += READ_U32(offset) + READ_U16(offset + 7); 502 } 503 504 /* Read instrument headers */ 505 for(uint16_t i = 0; i < num_instruments; ++i) { 506 uint16_t num_samples; 507 uint32_t sample_size_aggregate = 0; 508 509 num_samples = READ_U16(offset + 27); 510 memory_needed += num_samples * xm_sample_t.sizeof; 511 512 /* Instrument header size */ 513 uint32_t ins_header_size = READ_U32(offset); 514 if (ins_header_size == 0 || ins_header_size > INSTRUMENT_HEADER_LENGTH) 515 ins_header_size = INSTRUMENT_HEADER_LENGTH; 516 offset += ins_header_size; 517 518 for(uint16_t j = 0; j < num_samples; ++j) { 519 uint32_t sample_size; 520 521 sample_size = READ_U32(offset); 522 sample_size_aggregate += sample_size; 523 memory_needed += sample_size; 524 offset += 40; /* See comment in xm_load_module() */ 525 } 526 527 offset += sample_size_aggregate; 528 } 529 530 memory_needed += num_channels * xm_channel_context_t.sizeof; 531 memory_needed += xm_context_t.sizeof; 532 533 return memory_needed; 534 } 535 536 /** Populate the context from module data. 537 * 538 * @returns pointer to the memory pool 539 */ 540 char* xm_load_module(xm_context_t* ctx, const char* moddata, size_t moddata_length, char* mempool) { 541 size_t offset = 0; 542 xm_module_t* mod = &(ctx.module_); 543 544 ubyte READ_U8_BOUND(size_t offset, size_t bound) 545 { 546 return (offset < bound) ? *cast(uint8_t*)(moddata + offset) : 0; 547 } 548 549 ubyte READ_U8(size_t offset) 550 { 551 return READ_U8_BOUND(offset, moddata_length); 552 } 553 554 ushort READ_U16_BOUND(size_t offset, size_t bound) 555 { 556 return (cast(uint16_t)READ_U8(offset) | (cast(uint16_t)READ_U8((offset) + 1) << 8)); 557 } 558 559 ushort READ_U16(size_t offset) 560 { 561 return READ_U16_BOUND(offset, moddata_length); 562 } 563 564 uint READ_U32_BOUND(size_t offset, size_t bound) 565 { 566 return (cast(uint32_t)READ_U16(offset) | (cast(uint32_t)READ_U16((offset) + 2) << 16)); 567 } 568 569 uint READ_U32(size_t offset) 570 { 571 return READ_U32_BOUND(offset, moddata_length); 572 } 573 574 void READ_MEMCPY_BOUND(void* ptr, size_t offset, size_t length, size_t bound) 575 { 576 memcpy_pad(ptr, length, moddata, bound, offset); 577 } 578 579 void READ_MEMCPY(void* ptr, size_t offset, size_t length) 580 { 581 return READ_MEMCPY_BOUND(ptr, offset, length, moddata_length); 582 } 583 584 /* Read XM header */ 585 version(XM_STRINGS) 586 { 587 READ_MEMCPY(mod.name.ptr, offset + 17, MODULE_NAME_LENGTH); 588 READ_MEMCPY(mod.trackername.ptr, offset + 38, TRACKER_NAME_LENGTH); 589 } 590 offset += 60; 591 592 /* Read module header */ 593 uint32_t header_size = READ_U32(offset); 594 595 mod.length = READ_U16(offset + 4); 596 mod.restart_position = READ_U16(offset + 6); 597 mod.num_channels = READ_U16(offset + 8); 598 mod.num_patterns = READ_U16(offset + 10); 599 mod.num_instruments = READ_U16(offset + 12); 600 601 mod.patterns = cast(xm_pattern_t*)mempool; 602 mempool += mod.num_patterns * xm_pattern_t.sizeof; 603 604 mod.instruments = cast(xm_instrument_t*)mempool; 605 mempool += mod.num_instruments * xm_instrument_t.sizeof; 606 607 uint16_t flags = cast(ushort) READ_U32(offset + 14); 608 mod.frequency_type = (flags & (1 << 0)) ? XM_LINEAR_FREQUENCIES : XM_AMIGA_FREQUENCIES; 609 610 ctx.tempo = READ_U16(offset + 16); 611 ctx.bpm = READ_U16(offset + 18); 612 613 READ_MEMCPY(mod.pattern_table.ptr, offset + 20, PATTERN_ORDER_TABLE_LENGTH); 614 offset += header_size; 615 616 /* Read patterns */ 617 for(uint16_t i = 0; i < mod.num_patterns; ++i) { 618 uint16_t packed_patterndata_size = READ_U16(offset + 7); 619 xm_pattern_t* pat = mod.patterns + i; 620 621 pat.num_rows = READ_U16(offset + 5); 622 623 pat.slots = cast(xm_pattern_slot_t*)mempool; 624 mempool += mod.num_channels * pat.num_rows * xm_pattern_slot_t.sizeof; 625 626 /* Pattern header length */ 627 offset += READ_U32(offset); 628 629 if(packed_patterndata_size == 0) { 630 /* No pattern data is present */ 631 memset(pat.slots, 0, xm_pattern_slot_t.sizeof * pat.num_rows * mod.num_channels); 632 } else { 633 /* This isn't your typical for loop */ 634 for(uint16_t j = 0, k = 0; j < packed_patterndata_size; ++k) { 635 uint8_t note = READ_U8(offset + j); 636 xm_pattern_slot_t* slot = pat.slots + k; 637 638 if(note & (1 << 7)) { 639 /* MSB is set, this is a compressed packet */ 640 ++j; 641 642 if(note & (1 << 0)) { 643 /* Note follows */ 644 slot.note = READ_U8(offset + j); 645 ++j; 646 } else { 647 slot.note = 0; 648 } 649 650 if(note & (1 << 1)) { 651 /* Instrument follows */ 652 slot.instrument = READ_U8(offset + j); 653 ++j; 654 } else { 655 slot.instrument = 0; 656 } 657 658 if(note & (1 << 2)) { 659 /* Volume column follows */ 660 slot.volume_column = READ_U8(offset + j); 661 ++j; 662 } else { 663 slot.volume_column = 0; 664 } 665 666 if(note & (1 << 3)) { 667 /* Effect follows */ 668 slot.effect_type = READ_U8(offset + j); 669 ++j; 670 } else { 671 slot.effect_type = 0; 672 } 673 674 if(note & (1 << 4)) { 675 /* Effect parameter follows */ 676 slot.effect_param = READ_U8(offset + j); 677 ++j; 678 } else { 679 slot.effect_param = 0; 680 } 681 } else { 682 /* Uncompressed packet */ 683 slot.note = note; 684 slot.instrument = READ_U8(offset + j + 1); 685 slot.volume_column = READ_U8(offset + j + 2); 686 slot.effect_type = READ_U8(offset + j + 3); 687 slot.effect_param = READ_U8(offset + j + 4); 688 j += 5; 689 } 690 } 691 } 692 693 offset += packed_patterndata_size; 694 } 695 696 /* Read instruments */ 697 for(uint16_t i = 0; i < ctx.module_.num_instruments; ++i) { 698 xm_instrument_t* instr = mod.instruments + i; 699 700 /* Original FT2 would load instruments with a direct read into the 701 instrument data structure that was previously zeroed. This means 702 that if the declared length was less than INSTRUMENT_HEADER_LENGTH, 703 all excess data would be zeroed. This is used by the XM compressor 704 BoobieSqueezer. To implement this, bound all reads to the header size. */ 705 uint32_t ins_header_size = READ_U32(offset); 706 if (ins_header_size == 0 || ins_header_size > INSTRUMENT_HEADER_LENGTH) 707 ins_header_size = INSTRUMENT_HEADER_LENGTH; 708 709 version(XM_STRINGS) 710 { 711 READ_MEMCPY_BOUND(instr.name.ptr, offset + 4, INSTRUMENT_NAME_LENGTH, offset + ins_header_size); 712 instr.name[INSTRUMENT_NAME_LENGTH] = 0; 713 } 714 instr.num_samples = READ_U16_BOUND(offset + 27, offset + ins_header_size); 715 716 if(instr.num_samples > 0) { 717 /* Read extra header properties */ 718 READ_MEMCPY_BOUND(instr.sample_of_notes.ptr, offset + 33, NUM_NOTES, offset + ins_header_size); 719 720 instr.volume_envelope.num_points = READ_U8_BOUND(offset + 225, offset + ins_header_size); 721 if (instr.volume_envelope.num_points > NUM_ENVELOPE_POINTS) 722 instr.volume_envelope.num_points = NUM_ENVELOPE_POINTS; 723 724 instr.panning_envelope.num_points = READ_U8_BOUND(offset + 226, offset + ins_header_size); 725 if (instr.panning_envelope.num_points > NUM_ENVELOPE_POINTS) 726 instr.panning_envelope.num_points = NUM_ENVELOPE_POINTS; 727 728 for(uint8_t j = 0; j < instr.volume_envelope.num_points; ++j) { 729 instr.volume_envelope.points[j].frame = READ_U16_BOUND(offset + 129 + 4 * j, offset + ins_header_size); 730 instr.volume_envelope.points[j].value = READ_U16_BOUND(offset + 129 + 4 * j + 2, offset + ins_header_size); 731 } 732 733 for(uint8_t j = 0; j < instr.panning_envelope.num_points; ++j) { 734 instr.panning_envelope.points[j].frame = READ_U16_BOUND(offset + 177 + 4 * j, offset + ins_header_size); 735 instr.panning_envelope.points[j].value = READ_U16_BOUND(offset + 177 + 4 * j + 2, offset + ins_header_size); 736 } 737 738 instr.volume_envelope.sustain_point = READ_U8_BOUND(offset + 227, offset + ins_header_size); 739 instr.volume_envelope.loop_start_point = READ_U8_BOUND(offset + 228, offset + ins_header_size); 740 instr.volume_envelope.loop_end_point = READ_U8_BOUND(offset + 229, offset + ins_header_size); 741 742 instr.panning_envelope.sustain_point = READ_U8_BOUND(offset + 230, offset + ins_header_size); 743 instr.panning_envelope.loop_start_point = READ_U8_BOUND(offset + 231, offset + ins_header_size); 744 instr.panning_envelope.loop_end_point = READ_U8_BOUND(offset + 232, offset + ins_header_size); 745 746 uint8_t flags_ = READ_U8_BOUND(offset + 233, offset + ins_header_size); 747 instr.volume_envelope.enabled = ( flags_ & (1 << 0) ) != 0; 748 instr.volume_envelope.sustain_enabled = (flags_ & (1 << 1) ) != 0; 749 instr.volume_envelope.loop_enabled = ( flags_ & (1 << 2) ) != 0; 750 751 flags_ = READ_U8_BOUND(offset + 234, offset + ins_header_size); 752 instr.panning_envelope.enabled = flags_ & (1 << 0); 753 instr.panning_envelope.sustain_enabled = (flags_ & (1 << 1)) != 0; 754 instr.panning_envelope.loop_enabled = (flags_ & (1 << 2)) != 0; 755 756 instr.vibrato_type = READ_U8_BOUND(offset + 235, offset + ins_header_size); 757 if(instr.vibrato_type == 2) { 758 instr.vibrato_type = 1; 759 } else if(instr.vibrato_type == 1) { 760 instr.vibrato_type = 2; 761 } 762 instr.vibrato_sweep = READ_U8_BOUND(offset + 236, offset + ins_header_size); 763 instr.vibrato_depth = READ_U8_BOUND(offset + 237, offset + ins_header_size); 764 instr.vibrato_rate = READ_U8_BOUND(offset + 238, offset + ins_header_size); 765 instr.volume_fadeout = READ_U16_BOUND(offset + 239, offset + ins_header_size); 766 767 instr.samples = cast(xm_sample_t*)mempool; 768 mempool += instr.num_samples * xm_sample_t.sizeof; 769 } else { 770 instr.samples = null; 771 } 772 773 /* Instrument header size */ 774 offset += ins_header_size; 775 776 for(uint16_t j = 0; j < instr.num_samples; ++j) { 777 /* Read sample header */ 778 xm_sample_t* sample = instr.samples + j; 779 780 sample.length = READ_U32(offset); 781 sample.loop_start = READ_U32(offset + 4); 782 sample.loop_length = READ_U32(offset + 8); 783 sample.loop_end = sample.loop_start + sample.loop_length; 784 sample.volume = cast(float)READ_U8(offset + 12) / cast(float)0x40; 785 sample.finetune = cast(int8_t)READ_U8(offset + 13); 786 787 /* Fix invalid loop definitions */ 788 if (sample.loop_start > sample.length) 789 sample.loop_start = sample.length; 790 if (sample.loop_end > sample.length) 791 sample.loop_end = sample.length; 792 sample.loop_length = sample.loop_end - sample.loop_start; 793 794 uint8_t flags2 = READ_U8(offset + 14); 795 if((flags2 & 3) == 0 || sample.loop_length == 0) { 796 sample.loop_type = XM_NO_LOOP; 797 } else if((flags2 & 3) == 1) { 798 sample.loop_type = XM_FORWARD_LOOP; 799 } else { 800 sample.loop_type = XM_PING_PONG_LOOP; 801 } 802 803 sample.bits = (flags2 & (1 << 4)) ? 16 : 8; 804 805 sample.panning = cast(float)READ_U8(offset + 15) / cast(float)0xFF; 806 sample.relative_note = cast(int8_t)READ_U8(offset + 16); 807 version( XM_STRINGS) 808 { 809 READ_MEMCPY(sample.name.ptr, 18, SAMPLE_NAME_LENGTH); 810 } 811 sample.data8 = cast(int8_t*)mempool; 812 mempool += sample.length; 813 814 if(sample.bits == 16) { 815 sample.loop_start >>= 1; 816 sample.loop_length >>= 1; 817 sample.loop_end >>= 1; 818 sample.length >>= 1; 819 } 820 821 /* Notice that, even if there's a "sample header size" in the 822 instrument header, that value seems ignored, and might even 823 be wrong in some corrupted modules. */ 824 offset += 40; 825 } 826 827 for(uint16_t j = 0; j < instr.num_samples; ++j) { 828 /* Read sample data */ 829 xm_sample_t* sample = instr.samples + j; 830 uint32_t length = sample.length; 831 832 if(sample.bits == 16) { 833 int16_t v = 0; 834 for(uint32_t k = 0; k < length; ++k) { 835 v = cast(short)( v + cast(int16_t)READ_U16(offset + (k << 1)) ); 836 sample.data16[k] = v; 837 } 838 offset += sample.length << 1; 839 } else { 840 int8_t v = 0; 841 for(uint32_t k = 0; k < length; ++k) { 842 v = cast(byte)( v + cast(int8_t)READ_U8(offset + k) ); 843 sample.data8[k] = v; 844 } 845 offset += sample.length; 846 } 847 } 848 } 849 850 return mempool; 851 } 852 853 854 855 // context.c -- public API 856 857 int xm_create_context_safe(xm_context_t** ctxp, const char* moddata, size_t moddata_length, uint32_t rate) 858 { 859 size_t bytes_needed; 860 char* mempool; 861 xm_context_t* ctx; 862 863 if(XM_DEFENSIVE) 864 { 865 int ret = xm_check_sanity_preload(moddata, moddata_length); 866 if (ret != 0) 867 { 868 //("xm_check_sanity_preload() returned %i, module is not safe to load", ret); 869 return 1; 870 } 871 } 872 873 bytes_needed = xm_get_memory_needed_for_context(moddata, moddata_length); 874 mempool = cast(char*) malloc(bytes_needed); 875 if(mempool == null && bytes_needed > 0) { 876 /* malloc() failed, trouble ahead */ 877 //DEBUG("call to malloc() failed, returned %p", (void*)mempool); 878 return 2; 879 } 880 881 /* Initialize most of the fields to 0, 0.0f, null or false depending on type */ 882 memset(mempool, 0, bytes_needed); 883 884 ctx = (*ctxp = cast(xm_context_t*)mempool); 885 ctx.ctx_size = bytes_needed; /* Keep original requested size for xmconvert */ 886 mempool += xm_context_t.sizeof; 887 888 ctx.rate = rate; 889 mempool = xm_load_module(ctx, moddata, moddata_length, mempool); 890 891 ctx.channels = cast(xm_channel_context_t*)mempool; 892 mempool += ctx.module_.num_channels * (xm_channel_context_t).sizeof; 893 894 ctx.global_volume = 1.0f; 895 ctx.amplification = 0.25f; /* XXX: some bad modules may still clip. Find out something better. */ 896 ctx.next_rand = 24492; // see rng 897 898 version(XM_RAMPING) 899 { 900 ctx.volume_ramp = (1.0f / 128.0f); 901 } 902 903 for(uint8_t i = 0; i < ctx.module_.num_channels; ++i) { 904 xm_channel_context_t* ch = ctx.channels + i; 905 906 ch.ping = true; 907 ch.vibrato_waveform = XM_SINE_WAVEFORM; 908 ch.vibrato_waveform_retrigger = true; 909 ch.tremolo_waveform = XM_SINE_WAVEFORM; 910 ch.tremolo_waveform_retrigger = true; 911 912 ch.volume = ch.volume_envelope_volume = ch.fadeout_volume = 1.0f; 913 ch.panning = ch.panning_envelope_panning = .5f; 914 ch.actual_volume[0] = .0f; 915 ch.actual_volume[1] = .0f; 916 } 917 918 ctx.row_loop_count = cast(uint8_t*)mempool; 919 mempool += ctx.module_.length * MAX_NUM_ROWS * uint8_t.sizeof; 920 921 if(XM_DEFENSIVE) { 922 int ret = xm_check_sanity_postload(ctx); 923 if(ret != 0) 924 { 925 //DEBUG("xm_check_sanity_postload() returned %i, module is not safe to play", ret); 926 xm_free_context(ctx); 927 *ctxp = null; 928 return 1; 929 } 930 } 931 932 return 0; 933 } 934 935 void xm_free_context(xm_context_t* context) { 936 free(context); 937 } 938 939 void xm_set_max_loop_count(xm_context_t* context, uint8_t loopcnt) { 940 context.max_loop_count = loopcnt; 941 } 942 943 uint8_t xm_get_loop_count(xm_context_t* context) { 944 return context.loop_count; 945 } 946 947 948 949 void xm_seek(xm_context_t* ctx, uint8_t pot, uint8_t row, uint16_t tick) { 950 ctx.current_table_index = pot; 951 ctx.current_row = row; 952 ctx.current_tick = tick; 953 ctx.remaining_samples_in_tick = 0; 954 } 955 956 957 958 bool xm_mute_channel(xm_context_t* ctx, uint16_t channel, bool mute) { 959 bool old = ctx.channels[channel - 1].muted; 960 ctx.channels[channel - 1].muted = mute; 961 return old; 962 } 963 964 bool xm_mute_instrument(xm_context_t* ctx, uint16_t instr, bool mute) { 965 bool old = ctx.module_.instruments[instr - 1].muted; 966 ctx.module_.instruments[instr - 1].muted = mute; 967 return old; 968 } 969 970 971 972 version(XM_STRINGS) 973 { 974 const(char)* xm_get_module_name(xm_context_t* ctx) 975 { 976 return ctx.module_.name.ptr; 977 } 978 979 const(char)* xm_get_tracker_name(xm_context_t* ctx) 980 { 981 return ctx.module_.trackername.ptr; 982 } 983 } 984 else 985 { 986 const(char)* xm_get_module_name(xm_context_t* ctx) 987 { 988 return null; 989 } 990 991 const(char)* xm_get_tracker_name(xm_context_t* ctx) 992 { 993 return null; 994 } 995 } 996 997 uint16_t xm_get_number_of_channels(xm_context_t* ctx) { 998 return ctx.module_.num_channels; 999 } 1000 1001 uint16_t xm_get_module_length(xm_context_t* ctx) { 1002 return ctx.module_.length; 1003 } 1004 1005 uint16_t xm_get_number_of_patterns(xm_context_t* ctx) { 1006 return ctx.module_.num_patterns; 1007 } 1008 1009 uint16_t xm_get_number_of_rows(xm_context_t* ctx, uint16_t pattern) { 1010 return ctx.module_.patterns[pattern].num_rows; 1011 } 1012 1013 uint16_t xm_get_number_of_instruments(xm_context_t* ctx) { 1014 return ctx.module_.num_instruments; 1015 } 1016 1017 uint16_t xm_get_number_of_samples(xm_context_t* ctx, uint16_t instrument) { 1018 return ctx.module_.instruments[instrument - 1].num_samples; 1019 } 1020 1021 void* xm_get_sample_waveform(xm_context_t* ctx, uint16_t i, uint16_t s, size_t* size, uint8_t* bits) { 1022 *size = ctx.module_.instruments[i - 1].samples[s].length; 1023 *bits = ctx.module_.instruments[i - 1].samples[s].bits; 1024 return ctx.module_.instruments[i - 1].samples[s].data8; 1025 } 1026 1027 1028 1029 void xm_get_playing_speed(xm_context_t* ctx, uint16_t* bpm, uint16_t* tempo) { 1030 if(bpm) *bpm = ctx.bpm; 1031 if(tempo) *tempo = ctx.tempo; 1032 } 1033 1034 void xm_get_position(xm_context_t* ctx, uint8_t* pattern_index, uint8_t* pattern, uint8_t* row, uint64_t* samples) { 1035 if(pattern_index) *pattern_index = ctx.current_table_index; 1036 if(pattern) *pattern = ctx.module_.pattern_table[ctx.current_table_index]; 1037 if(row) *row = ctx.current_row; 1038 if(samples) *samples = ctx.generated_samples; 1039 } 1040 1041 uint64_t xm_get_latest_trigger_of_instrument(xm_context_t* ctx, uint16_t instr) { 1042 return ctx.module_.instruments[instr - 1].latest_trigger; 1043 } 1044 1045 uint64_t xm_get_latest_trigger_of_sample(xm_context_t* ctx, uint16_t instr, uint16_t sample) { 1046 return ctx.module_.instruments[instr - 1].samples[sample].latest_trigger; 1047 } 1048 1049 uint64_t xm_get_latest_trigger_of_channel(xm_context_t* ctx, uint16_t chn) { 1050 return ctx.channels[chn - 1].latest_trigger; 1051 } 1052 1053 bool xm_is_channel_active(xm_context_t* ctx, uint16_t chn) { 1054 xm_channel_context_t* ch = ctx.channels + (chn - 1); 1055 return ch.instrument != null && ch.sample != null && ch.sample_position >= 0; 1056 } 1057 1058 float xm_get_frequency_of_channel(xm_context_t* ctx, uint16_t chn) { 1059 return ctx.channels[chn - 1].frequency; 1060 } 1061 1062 float xm_get_volume_of_channel(xm_context_t* ctx, uint16_t chn) { 1063 return ctx.channels[chn - 1].volume * ctx.global_volume; 1064 } 1065 1066 float xm_get_panning_of_channel(xm_context_t* ctx, uint16_t chn) { 1067 return ctx.channels[chn - 1].panning; 1068 } 1069 1070 uint16_t xm_get_instrument_of_channel(xm_context_t* ctx, uint16_t chn) 1071 { 1072 xm_channel_context_t* ch = ctx.channels + (chn - 1); 1073 if(ch.instrument == null) return 0; 1074 return cast(ushort)( 1 + (ch.instrument - ctx.module_.instruments) ); 1075 } 1076 1077 1078 // play.c 1079 1080 /* Author: Romain "Artefact2" Dalmaso <artefact2@gmail.com> */ 1081 /* Contributor: Daniel Oaks <daniel@danieloaks.net> */ 1082 1083 /* This program is free software. It comes without any warranty, to the 1084 * extent permitted by applicable law. You can redistribute it and/or 1085 * modify it under the terms of the Do What The Fuck You Want To Public 1086 * License, Version 2, as published by Sam Hocevar. See 1087 * http://sam.zoy.org/wtfpl/COPYING for more details. */ 1088 1089 /* ----- Other oddities ----- */ 1090 1091 enum XM_TRIGGER_KEEP_VOLUME = (1 << 0); 1092 enum XM_TRIGGER_KEEP_PERIOD = (1 << 1); 1093 enum XM_TRIGGER_KEEP_SAMPLE_POSITION = (1 << 2); 1094 enum XM_TRIGGER_KEEP_ENVELOPE = (1 << 3); 1095 1096 enum AMIGA_FREQ_SCALE = 1024; 1097 1098 static immutable uint32_t[13] amiga_frequencies = 1099 [ 1100 1712*AMIGA_FREQ_SCALE, 1616*AMIGA_FREQ_SCALE, 1525*AMIGA_FREQ_SCALE, 1440*AMIGA_FREQ_SCALE, /* C-2, C#2, D-2, D#2 */ 1101 1357*AMIGA_FREQ_SCALE, 1281*AMIGA_FREQ_SCALE, 1209*AMIGA_FREQ_SCALE, 1141*AMIGA_FREQ_SCALE, /* E-2, F-2, F#2, G-2 */ 1102 1077*AMIGA_FREQ_SCALE, 1017*AMIGA_FREQ_SCALE, 961*AMIGA_FREQ_SCALE, 907*AMIGA_FREQ_SCALE, /* G#2, A-2, A#2, B-2 */ 1103 856*AMIGA_FREQ_SCALE, /* C-3 */ 1104 ]; 1105 1106 static immutable float[16] multi_retrig_add = 1107 [ 1108 0.0f, -1.0f, -2.0f, -4.0f, /* 0, 1, 2, 3 */ 1109 -8.0f, -16.0f, 0.0f, 0.0f, /* 4, 5, 6, 7 */ 1110 0.0f, 1.0f, 2.0f, 4.0f, /* 8, 9, A, B */ 1111 8.0f, 16.0f, 0.0f, 0.0f /* C, D, E, F */ 1112 ]; 1113 1114 static const float[16] multi_retrig_multiply = 1115 [ 1116 1.0f, 1.0f, 1.0f, 1.0f, /* 0, 1, 2, 3 */ 1117 1.0f, 1.0f, .6666667f, .5f, /* 4, 5, 6, 7 */ 1118 1.0f, 1.0f, 1.0f, 1.0f, /* 8, 9, A, B */ 1119 1.0f, 1.0f, 1.5f, 2.0f /* C, D, E, F */ 1120 ]; 1121 1122 /*#define XM_CLAMP_UP1F(vol, limit) do { \ 1123 if((vol) > (limit)) (vol) = (limit); \ 1124 } while(0) 1125 1126 #define XM_CLAMP_UP(vol) XM_CLAMP_UP1F((vol), 1.0f) 1127 1128 #define XM_CLAMP_DOWN1F(vol, limit) do { \ 1129 if((vol) < (limit)) (vol) = (limit); \ 1130 } while(0) 1131 #define XM_CLAMP_DOWN(vol) XM_CLAMP_DOWN1F((vol), .0f) 1132 1133 #define XM_CLAMP2F(vol, up, down) do { \ 1134 if((vol) > (up)) (vol) = (up); \ 1135 else if((vol) < (down)) (vol) = (down); \ 1136 } while(0) 1137 #define XM_CLAMP(vol) XM_CLAMP2F((vol), 1.0f, .0f) 1138 1139 */ 1140 1141 void XM_SLIDE_TOWARDS(ref float val, float goal, float incr) 1142 { 1143 if (val > goal) 1144 { 1145 val -= incr; 1146 if (val < goal) val = goal; 1147 } 1148 else if (val < goal) 1149 { 1150 val += incr; 1151 if (val > goal) val = goal; 1152 } 1153 } 1154 1155 float XM_LERP(float u, float v, float t) 1156 { 1157 return u + t * (v - u); 1158 } 1159 1160 float XM_INVERSE_LERP(float u, float v, float lerp) 1161 { 1162 return (lerp - u) / (v - u); 1163 } 1164 1165 bool NOTE_IS_VALID(int n) 1166 { 1167 return (n > 0) && (n < 97); 1168 } 1169 1170 /* ----- Function definitions ----- */ 1171 1172 float xm_waveform(xm_context_t* context, xm_waveform_type_t waveform, uint8_t step) { 1173 step %= 0x40; 1174 switch(waveform) 1175 { 1176 1177 case XM_SINE_WAVEFORM: 1178 /* Why not use a table? For saving space, and because there's 1179 * very very little actual performance gain. */ 1180 return -fast_sin(2.0f * 3.141592f * cast(float)step / cast(float)0x40); 1181 1182 case XM_RAMP_DOWN_WAVEFORM: 1183 /* Ramp down: 1.0f when step = 0; -1.0f when step = 0x40 */ 1184 return cast(float)(0x20 - step) / 0x20; 1185 1186 case XM_SQUARE_WAVEFORM: 1187 /* Square with a 50% duty */ 1188 return (step >= 0x20) ? 1.0f : -1.0f; 1189 1190 case XM_RANDOM_WAVEFORM: 1191 /* Use the POSIX.1-2001 example, just to be deterministic 1192 * across different machines */ 1193 context.next_rand = context.next_rand * 1103515245 + 12345; 1194 return cast(float)((context.next_rand >> 16) & 0x7FFF) / cast(float)0x4000 - 1.0f; 1195 1196 case XM_RAMP_UP_WAVEFORM: 1197 /* Ramp up: -1.0f when step = 0; 1.0f when step = 0x40 */ 1198 return cast(float)(step - 0x20) / 0x20; 1199 1200 default: 1201 break; 1202 1203 } 1204 1205 return .0f; 1206 } 1207 1208 void xm_autovibrato(xm_context_t* ctx, xm_channel_context_t* ch) { 1209 if(ch.instrument == null || ch.instrument.vibrato_depth == 0){ 1210 if (ch.autovibrato_note_offset){ 1211 ch.autovibrato_note_offset = 0.0f; 1212 xm_update_frequency(ctx, ch); 1213 } 1214 return; 1215 } 1216 xm_instrument_t* instr = ch.instrument; 1217 float sweep = 1.0f; 1218 1219 if(ch.autovibrato_ticks < instr.vibrato_sweep) { 1220 /* No idea if this is correct, but it sounds close enough… */ 1221 sweep = XM_LERP(0.0f, 1.0f, cast(float)ch.autovibrato_ticks / cast(float)instr.vibrato_sweep); 1222 } 1223 1224 uint step = ((ch.autovibrato_ticks++) * instr.vibrato_rate) >> 2; 1225 ch.autovibrato_note_offset = .25f * xm_waveform(ctx, instr.vibrato_type, cast(ubyte)step) 1226 * cast(float)instr.vibrato_depth / cast(float)0xF * sweep; 1227 xm_update_frequency(ctx, ch); 1228 } 1229 1230 void xm_vibrato(xm_context_t* ctx, xm_channel_context_t* ch, uint8_t param) { 1231 ch.vibrato_ticks += (param >> 4); 1232 ch.vibrato_note_offset = 1233 -2.0f 1234 * xm_waveform(ctx, ch.vibrato_waveform, cast(ubyte)ch.vibrato_ticks) 1235 * cast(float)(param & 0x0F) / cast(float)0xF; 1236 xm_update_frequency(ctx, ch); 1237 } 1238 1239 void xm_tremolo(xm_context_t* ctx, xm_channel_context_t* ch, uint8_t param, uint16_t pos) { 1240 uint step = pos * (param >> 4); 1241 /* Not so sure about this, it sounds correct by ear compared with 1242 * MilkyTracker, but it could come from other bugs */ 1243 ch.tremolo_volume = -1.0f * xm_waveform(ctx, ch.tremolo_waveform, cast(ubyte)step) 1244 * cast(float)(param & 0x0F) / cast(float)0xF; 1245 } 1246 1247 void xm_arpeggio(xm_context_t* ctx, xm_channel_context_t* ch, uint8_t param, uint16_t tick) { 1248 switch(tick % 3) { 1249 case 0: 1250 ch.arp_in_progress = false; 1251 ch.arp_note_offset = 0; 1252 break; 1253 case 2: 1254 ch.arp_in_progress = true; 1255 ch.arp_note_offset = param >> 4; 1256 break; 1257 case 1: 1258 ch.arp_in_progress = true; 1259 ch.arp_note_offset = param & 0x0F; 1260 break; 1261 1262 default: 1263 assert(false); 1264 } 1265 1266 xm_update_frequency(ctx, ch); 1267 } 1268 1269 void xm_tone_portamento(xm_context_t* ctx, xm_channel_context_t* ch) 1270 { 1271 /* 3xx called without a note, wait until we get an actual 1272 * target note. */ 1273 if(ch.tone_portamento_target_period == 0.0f) 1274 return; 1275 1276 if(ch.period != ch.tone_portamento_target_period) 1277 { 1278 XM_SLIDE_TOWARDS(ch.period, 1279 ch.tone_portamento_target_period, 1280 (ctx.module_.frequency_type == XM_LINEAR_FREQUENCIES ? 4.0f : 1.0f) * ch.tone_portamento_param); 1281 xm_update_frequency(ctx, ch); 1282 } 1283 } 1284 1285 void xm_pitch_slide(xm_context_t* ctx, xm_channel_context_t* ch, float period_offset) { 1286 /* Don't ask about the 4.0f coefficient. I found mention of it 1287 * nowhere. Found by ear™. */ 1288 if(ctx.module_.frequency_type == XM_LINEAR_FREQUENCIES) { 1289 period_offset *= 4.0f; 1290 } 1291 1292 ch.period += period_offset; 1293 if (ch.period < 0) ch.period = 0; 1294 /* XXX: upper bound of period ? */ 1295 1296 xm_update_frequency(ctx, ch); 1297 } 1298 1299 void xm_panning_slide(xm_channel_context_t* ch, uint8_t rawval) { 1300 float f; 1301 1302 if((rawval & 0xF0) && (rawval & 0x0F)) { 1303 /* Illegal state */ 1304 return; 1305 } 1306 1307 if(rawval & 0xF0) { 1308 /* Slide right */ 1309 f = cast(float)(rawval >> 4) / cast(float)0xFF; 1310 ch.panning += f; 1311 if (ch.panning > 1) 1312 ch.panning = 1; 1313 } else { 1314 /* Slide left */ 1315 f = cast(float)(rawval & 0x0F) / cast(float)0xFF; 1316 ch.panning -= f; 1317 if (ch.panning < 0) 1318 ch.panning = 0; 1319 } 1320 } 1321 1322 void xm_volume_slide(xm_channel_context_t* ch, uint8_t rawval) { 1323 float f; 1324 1325 if((rawval & 0xF0) && (rawval & 0x0F)) { 1326 /* Illegal state */ 1327 return; 1328 } 1329 1330 if(rawval & 0xF0) { 1331 /* Slide up */ 1332 f = cast(float)(rawval >> 4) / cast(float)0x40; 1333 ch.volume += f; 1334 if (ch.volume > 1) 1335 ch.volume = 1; 1336 } else { 1337 /* Slide down */ 1338 f = cast(float)(rawval & 0x0F) / cast(float)0x40; 1339 ch.volume -= f; 1340 if (ch.volume < 0) 1341 ch.volume = 0; 1342 } 1343 } 1344 1345 float xm_envelope_lerp(xm_envelope_point_t* a, xm_envelope_point_t* b, uint16_t pos) { 1346 /* Linear interpolation between two envelope points */ 1347 if(pos <= a.frame) return a.value; 1348 else if(pos >= b.frame) return b.value; 1349 else { 1350 float p = cast(float)(pos - a.frame) / cast(float)(b.frame - a.frame); 1351 return a.value * (1 - p) + b.value * p; 1352 } 1353 } 1354 1355 void xm_post_pattern_change(xm_context_t* ctx) { 1356 /* Loop if necessary */ 1357 if(ctx.current_table_index >= ctx.module_.length) 1358 { 1359 ctx.current_table_index = cast(ubyte)(ctx.module_.restart_position); 1360 } 1361 } 1362 1363 float xm_linear_period(float note) { 1364 return 7680.0f - note * 64.0f; 1365 } 1366 1367 float xm_linear_frequency(float period) { 1368 return 8363.0f * fast_pow(2.0f, (4608.0f - period) / 768.0f); 1369 } 1370 1371 float xm_amiga_period(float note) { 1372 uint intnote = cast(uint)note; 1373 uint8_t a = intnote % 12; 1374 int8_t octave = cast(int8_t)(note / 12.0f - 2); 1375 int32_t p1 = amiga_frequencies[a], p2 = amiga_frequencies[a + 1]; 1376 1377 if(octave > 0) { 1378 p1 >>= octave; 1379 p2 >>= octave; 1380 } else if(octave < 0) { 1381 p1 <<= (-cast(int)octave); 1382 p2 <<= (-cast(int)octave); 1383 } 1384 1385 return XM_LERP(p1, p2, note - intnote) / AMIGA_FREQ_SCALE; 1386 } 1387 1388 float xm_amiga_frequency(float period) { 1389 if(period == .0f) return .0f; 1390 1391 /* This is the PAL value. No reason to choose this one over the 1392 * NTSC value. */ 1393 return 7093789.2f / (period * 2.0f); 1394 } 1395 1396 float xm_period(xm_context_t* ctx, float note) 1397 { 1398 switch(ctx.module_.frequency_type) 1399 { 1400 case XM_LINEAR_FREQUENCIES: 1401 return xm_linear_period(note); 1402 case XM_AMIGA_FREQUENCIES: 1403 return xm_amiga_period(note); 1404 default: 1405 } 1406 return .0f; 1407 } 1408 1409 float xm_frequency(xm_context_t* ctx, float period, float note_offset, float period_offset) { 1410 uint8_t a; 1411 int8_t octave; 1412 float note; 1413 int32_t p1, p2; 1414 1415 switch(ctx.module_.frequency_type) 1416 { 1417 1418 case XM_LINEAR_FREQUENCIES: 1419 return xm_linear_frequency(period - 64.0f * note_offset - 16.0f * period_offset); 1420 1421 case XM_AMIGA_FREQUENCIES: 1422 if(note_offset == 0) { 1423 /* A chance to escape from insanity */ 1424 return xm_amiga_frequency(period + 16.0f * period_offset); 1425 } 1426 1427 /* FIXME: this is very crappy at best */ 1428 a = octave = 0; 1429 1430 /* Find the octave of the current period */ 1431 period *= AMIGA_FREQ_SCALE; 1432 if(period > amiga_frequencies[0]) { 1433 --octave; 1434 while(period > (amiga_frequencies[0] << (-cast(int)octave))) --octave; 1435 } else if(period < amiga_frequencies[12]) { 1436 ++octave; 1437 while(period < (amiga_frequencies[12] >> octave)) ++octave; 1438 } 1439 1440 /* Find the smallest note closest to the current period */ 1441 for(uint8_t i = 0; i < 12; ++i) { 1442 p1 = amiga_frequencies[i], p2 = amiga_frequencies[i + 1]; 1443 1444 if(octave > 0) { 1445 p1 >>= octave; 1446 p2 >>= octave; 1447 } else if(octave < 0) { 1448 p1 <<= (-cast(int)octave); 1449 p2 <<= (-cast(int)octave); 1450 } 1451 1452 if(p2 <= period && period <= p1) { 1453 a = i; 1454 break; 1455 } 1456 } 1457 1458 /*if(XM_DEBUG && (p1 < period || p2 > period)) 1459 { 1460 //DEBUG("%" PRId32 " <= %f <= %" PRId32 " should hold but doesn't, this is a bug", p2, period, p1); 1461 assert(false); 1462 }*/ 1463 1464 note = 12.0f * (octave + 2) + a + XM_INVERSE_LERP(p1, p2, period); 1465 1466 return xm_amiga_frequency(xm_amiga_period(note + note_offset) + 16.0f * period_offset); 1467 1468 default: 1469 } 1470 1471 return .0f; 1472 } 1473 1474 void xm_update_frequency(xm_context_t* ctx, xm_channel_context_t* ch) { 1475 ch.frequency = xm_frequency( 1476 ctx, ch.period, 1477 ch.arp_note_offset, 1478 ch.vibrato_note_offset + ch.autovibrato_note_offset 1479 ); 1480 ch.step = ch.frequency / ctx.rate; 1481 } 1482 1483 void xm_handle_note_and_instrument(xm_context_t* ctx, xm_channel_context_t* ch, 1484 xm_pattern_slot_t* s) { 1485 if(s.instrument > 0) { 1486 if(ch.current.HAS_TONE_PORTAMENTO() && ch.instrument != null && ch.sample != null) { 1487 /* Tone portamento in effect, unclear stuff happens */ 1488 xm_trigger_note(ctx, ch, XM_TRIGGER_KEEP_PERIOD | XM_TRIGGER_KEEP_SAMPLE_POSITION); 1489 } else if(s.note == 0 && ch.sample != null) { 1490 /* Ghost instrument, trigger note */ 1491 /* Sample position is kept, but envelopes are reset */ 1492 xm_trigger_note(ctx, ch, XM_TRIGGER_KEEP_SAMPLE_POSITION); 1493 } else if(s.instrument > ctx.module_.num_instruments) { 1494 /* Invalid instrument, Cut current note */ 1495 xm_cut_note(ch); 1496 ch.instrument = null; 1497 ch.sample = null; 1498 } else { 1499 ch.instrument = ctx.module_.instruments + (s.instrument - 1); 1500 } 1501 } 1502 1503 if(NOTE_IS_VALID(s.note)) { 1504 /* Yes, the real note number is s.note -1. Try finding 1505 * THAT in any of the specs! :-) */ 1506 1507 xm_instrument_t* instr = ch.instrument; 1508 1509 if(ch.current.HAS_TONE_PORTAMENTO() && instr != null && ch.sample != null) { 1510 /* Tone portamento in effect */ 1511 ch.note = s.note + ch.sample.relative_note + ch.sample.finetune / 128.0f - 1.0f; 1512 ch.tone_portamento_target_period = xm_period(ctx, ch.note); 1513 } else if(instr == null || ch.instrument.num_samples == 0) { 1514 /* Bad instrument */ 1515 xm_cut_note(ch); 1516 } else { 1517 if(instr.sample_of_notes[s.note - 1] < instr.num_samples) { 1518 version(XM_RAMPING) 1519 { 1520 for(uint z = 0; z < XM_SAMPLE_RAMPING_POINTS; ++z) { 1521 ch.end_of_previous_sample[z] = xm_next_of_sample(ch); 1522 } 1523 ch.frame_count = 0; 1524 } 1525 ch.sample = instr.samples + instr.sample_of_notes[s.note - 1]; 1526 ch.orig_note = ch.note = s.note + ch.sample.relative_note 1527 + ch.sample.finetune / 128.0f - 1.0f; 1528 if(s.instrument > 0) { 1529 xm_trigger_note(ctx, ch, 0); 1530 } else { 1531 /* Ghost note: keep old volume */ 1532 xm_trigger_note(ctx, ch, XM_TRIGGER_KEEP_VOLUME); 1533 } 1534 } else { 1535 /* Bad sample */ 1536 xm_cut_note(ch); 1537 } 1538 } 1539 } else if(s.note == 97) { 1540 /* Key Off */ 1541 xm_key_off(ch); 1542 } 1543 1544 switch(s.volume_column >> 4) { 1545 1546 case 0x5: 1547 if(s.volume_column > 0x50) break; 1548 goto case 0x1; 1549 1550 case 0x1: 1551 case 0x2: 1552 case 0x3: 1553 case 0x4: 1554 /* Set volume */ 1555 ch.volume = cast(float)(s.volume_column - 0x10) / cast(float)0x40; 1556 break; 1557 1558 case 0x8: /* Fine volume slide down */ 1559 xm_volume_slide(ch, s.volume_column & 0x0F); 1560 break; 1561 1562 case 0x9: /* Fine volume slide up */ 1563 xm_volume_slide(ch, cast(ubyte)(s.volume_column << 4)); 1564 break; 1565 1566 case 0xA: /* Set vibrato speed */ 1567 ch.vibrato_param = (ch.vibrato_param & 0x0F) | ((s.volume_column & 0x0F) << 4); 1568 break; 1569 1570 case 0xC: /* Set panning */ 1571 ch.panning = cast(float)( 1572 ((s.volume_column & 0x0F) << 4) | (s.volume_column & 0x0F) 1573 ) / cast(float)0xFF; 1574 break; 1575 1576 case 0xF: /* Tone portamento */ 1577 if(s.volume_column & 0x0F) { 1578 ch.tone_portamento_param = ((s.volume_column & 0x0F) << 4) 1579 | (s.volume_column & 0x0F); 1580 } 1581 break; 1582 1583 default: 1584 break; 1585 1586 } 1587 1588 switch(s.effect_type) { 1589 1590 case 1: /* 1xx: Portamento up */ 1591 if(s.effect_param > 0) { 1592 ch.portamento_up_param = s.effect_param; 1593 } 1594 break; 1595 1596 case 2: /* 2xx: Portamento down */ 1597 if(s.effect_param > 0) { 1598 ch.portamento_down_param = s.effect_param; 1599 } 1600 break; 1601 1602 case 3: /* 3xx: Tone portamento */ 1603 if(s.effect_param > 0) { 1604 ch.tone_portamento_param = s.effect_param; 1605 } 1606 break; 1607 1608 case 4: /* 4xy: Vibrato */ 1609 if(s.effect_param & 0x0F) { 1610 /* Set vibrato depth */ 1611 ch.vibrato_param = (ch.vibrato_param & 0xF0) | (s.effect_param & 0x0F); 1612 } 1613 if(s.effect_param >> 4) { 1614 /* Set vibrato speed */ 1615 ch.vibrato_param = (s.effect_param & 0xF0) | (ch.vibrato_param & 0x0F); 1616 } 1617 break; 1618 1619 case 5: /* 5xy: Tone portamento + Volume slide */ 1620 if(s.effect_param > 0) { 1621 ch.volume_slide_param = s.effect_param; 1622 } 1623 break; 1624 1625 case 6: /* 6xy: Vibrato + Volume slide */ 1626 if(s.effect_param > 0) { 1627 ch.volume_slide_param = s.effect_param; 1628 } 1629 break; 1630 1631 case 7: /* 7xy: Tremolo */ 1632 if(s.effect_param & 0x0F) { 1633 /* Set tremolo depth */ 1634 ch.tremolo_param = (ch.tremolo_param & 0xF0) | (s.effect_param & 0x0F); 1635 } 1636 if(s.effect_param >> 4) { 1637 /* Set tremolo speed */ 1638 ch.tremolo_param = (s.effect_param & 0xF0) | (ch.tremolo_param & 0x0F); 1639 } 1640 break; 1641 1642 case 8: /* 8xx: Set panning */ 1643 ch.panning = cast(float)s.effect_param / cast(float)0xFF; 1644 break; 1645 1646 case 9: /* 9xx: Sample offset */ 1647 if(ch.sample != null && NOTE_IS_VALID(s.note)) { 1648 uint32_t final_offset = s.effect_param << (ch.sample.bits == 16 ? 7 : 8); 1649 if(final_offset >= ch.sample.length) { 1650 /* Pretend the sample dosen't loop and is done playing */ 1651 ch.sample_position = -1; 1652 break; 1653 } 1654 ch.sample_position = final_offset; 1655 } 1656 break; 1657 1658 case 0xA: /* Axy: Volume slide */ 1659 if(s.effect_param > 0) { 1660 ch.volume_slide_param = s.effect_param; 1661 } 1662 break; 1663 1664 case 0xB: /* Bxx: Position jump */ 1665 if(s.effect_param < ctx.module_.length) { 1666 ctx.position_jump = true; 1667 ctx.jump_dest = s.effect_param; 1668 ctx.jump_row = 0; 1669 } 1670 break; 1671 1672 case 0xC: /* Cxx: Set volume */ 1673 ch.volume = cast(float)((s.effect_param > 0x40) 1674 ? 0x40 : s.effect_param) / cast(float)0x40; 1675 break; 1676 1677 case 0xD: /* Dxx: Pattern break */ 1678 /* Jump after playing this line */ 1679 ctx.pattern_break = true; 1680 ctx.jump_row = (s.effect_param >> 4) * 10 + (s.effect_param & 0x0F); 1681 break; 1682 1683 case 0xE: /* EXy: Extended command */ 1684 switch(s.effect_param >> 4) { 1685 1686 case 1: /* E1y: Fine portamento up */ 1687 if(s.effect_param & 0x0F) { 1688 ch.fine_portamento_up_param = s.effect_param & 0x0F; 1689 } 1690 xm_pitch_slide(ctx, ch, -cast(int)(ch.fine_portamento_up_param)); 1691 break; 1692 1693 case 2: /* E2y: Fine portamento down */ 1694 if(s.effect_param & 0x0F) { 1695 ch.fine_portamento_down_param = s.effect_param & 0x0F; 1696 } 1697 xm_pitch_slide(ctx, ch, ch.fine_portamento_down_param); 1698 break; 1699 1700 case 4: /* E4y: Set vibrato control */ 1701 ch.vibrato_waveform = s.effect_param & 3; 1702 ch.vibrato_waveform_retrigger = !((s.effect_param >> 2) & 1); 1703 break; 1704 1705 case 5: /* E5y: Set finetune */ 1706 if(NOTE_IS_VALID(ch.current.note) && ch.sample != null) { 1707 ch.note = ch.current.note + ch.sample.relative_note + 1708 cast(float)(((s.effect_param & 0x0F) - 8) << 4) / 128.0f - 1.0f; 1709 ch.period = xm_period(ctx, ch.note); 1710 xm_update_frequency(ctx, ch); 1711 } 1712 break; 1713 1714 case 6: /* E6y: Pattern loop */ 1715 if(s.effect_param & 0x0F) { 1716 if((s.effect_param & 0x0F) == ch.pattern_loop_count) { 1717 /* Loop is over */ 1718 ch.pattern_loop_count = 0; 1719 break; 1720 } 1721 1722 /* Jump to the beginning of the loop */ 1723 ch.pattern_loop_count++; 1724 ctx.position_jump = true; 1725 ctx.jump_row = ch.pattern_loop_origin; 1726 ctx.jump_dest = ctx.current_table_index; 1727 } else { 1728 /* Set loop start point */ 1729 ch.pattern_loop_origin = ctx.current_row; 1730 /* Replicate FT2 E60 bug */ 1731 ctx.jump_row = ch.pattern_loop_origin; 1732 } 1733 break; 1734 1735 case 7: /* E7y: Set tremolo control */ 1736 ch.tremolo_waveform = s.effect_param & 3; 1737 ch.tremolo_waveform_retrigger = !((s.effect_param >> 2) & 1); 1738 break; 1739 1740 case 0xA: /* EAy: Fine volume slide up */ 1741 if(s.effect_param & 0x0F) { 1742 ch.fine_volume_slide_param = s.effect_param & 0x0F; 1743 } 1744 xm_volume_slide(ch, cast(ubyte)(ch.fine_volume_slide_param << 4)); 1745 break; 1746 1747 case 0xB: /* EBy: Fine volume slide down */ 1748 if(s.effect_param & 0x0F) { 1749 ch.fine_volume_slide_param = s.effect_param & 0x0F; 1750 } 1751 xm_volume_slide(ch, ch.fine_volume_slide_param); 1752 break; 1753 1754 case 0xD: /* EDy: Note delay */ 1755 /* XXX: figure this out better. EDx triggers 1756 * the note even when there no note and no 1757 * instrument. But ED0 acts like like a ghost 1758 * note, EDx (x ≠ 0) does not. */ 1759 if(s.note == 0 && s.instrument == 0) { 1760 uint flags = XM_TRIGGER_KEEP_VOLUME; 1761 1762 if(ch.current.effect_param & 0x0F) { 1763 ch.note = ch.orig_note; 1764 xm_trigger_note(ctx, ch, flags); 1765 } else { 1766 xm_trigger_note( 1767 ctx, ch, 1768 flags 1769 | XM_TRIGGER_KEEP_PERIOD 1770 | XM_TRIGGER_KEEP_SAMPLE_POSITION 1771 ); 1772 } 1773 } 1774 break; 1775 1776 case 0xE: /* EEy: Pattern delay */ 1777 ctx.extra_ticks = cast(ushort)( (ch.current.effect_param & 0x0F) * ctx.tempo ); 1778 break; 1779 1780 default: 1781 break; 1782 1783 } 1784 break; 1785 1786 case 0xF: /* Fxx: Set tempo/BPM */ 1787 if(s.effect_param > 0) { 1788 if(s.effect_param <= 0x1F) { 1789 ctx.tempo = s.effect_param; 1790 } else { 1791 ctx.bpm = s.effect_param; 1792 } 1793 } 1794 break; 1795 1796 case 16: /* Gxx: Set global volume */ 1797 ctx.global_volume = cast(float)((s.effect_param > 0x40) 1798 ? 0x40 : s.effect_param) / cast(float)0x40; 1799 break; 1800 1801 case 17: /* Hxy: Global volume slide */ 1802 if(s.effect_param > 0) { 1803 ch.global_volume_slide_param = s.effect_param; 1804 } 1805 break; 1806 1807 case 21: /* Lxx: Set envelope position */ 1808 ch.volume_envelope_frame_count = s.effect_param; 1809 ch.panning_envelope_frame_count = s.effect_param; 1810 break; 1811 1812 case 25: /* Pxy: Panning slide */ 1813 if(s.effect_param > 0) { 1814 ch.panning_slide_param = s.effect_param; 1815 } 1816 break; 1817 1818 case 27: /* Rxy: Multi retrig note */ 1819 if(s.effect_param > 0) { 1820 if((s.effect_param >> 4) == 0) { 1821 /* Keep previous x value */ 1822 ch.multi_retrig_param = (ch.multi_retrig_param & 0xF0) | (s.effect_param & 0x0F); 1823 } else { 1824 ch.multi_retrig_param = s.effect_param; 1825 } 1826 } 1827 break; 1828 1829 case 29: /* Txy: Tremor */ 1830 if(s.effect_param > 0) { 1831 /* Tremor x and y params do not appear to be separately 1832 * kept in memory, unlike Rxy */ 1833 ch.tremor_param = s.effect_param; 1834 } 1835 break; 1836 1837 case 33: /* Xxy: Extra stuff */ 1838 switch(s.effect_param >> 4) { 1839 1840 case 1: /* X1y: Extra fine portamento up */ 1841 if(s.effect_param & 0x0F) { 1842 ch.extra_fine_portamento_up_param = s.effect_param & 0x0F; 1843 } 1844 xm_pitch_slide(ctx, ch, -1.0f * ch.extra_fine_portamento_up_param); 1845 break; 1846 1847 case 2: /* X2y: Extra fine portamento down */ 1848 if(s.effect_param & 0x0F) { 1849 ch.extra_fine_portamento_down_param = s.effect_param & 0x0F; 1850 } 1851 xm_pitch_slide(ctx, ch, ch.extra_fine_portamento_down_param); 1852 break; 1853 1854 default: 1855 break; 1856 1857 } 1858 break; 1859 1860 default: 1861 break; 1862 1863 } 1864 } 1865 1866 void xm_trigger_note(xm_context_t* ctx, xm_channel_context_t* ch, uint flags) { 1867 if(!(flags & XM_TRIGGER_KEEP_SAMPLE_POSITION)) { 1868 ch.sample_position = 0.0f; 1869 ch.ping = true; 1870 } 1871 1872 if(ch.sample != null) { 1873 if(!(flags & XM_TRIGGER_KEEP_VOLUME)) { 1874 ch.volume = ch.sample.volume; 1875 } 1876 1877 ch.panning = ch.sample.panning; 1878 } 1879 1880 if(!(flags & XM_TRIGGER_KEEP_ENVELOPE)) { 1881 ch.sustained = true; 1882 ch.fadeout_volume = ch.volume_envelope_volume = 1.0f; 1883 ch.panning_envelope_panning = .5f; 1884 ch.volume_envelope_frame_count = ch.panning_envelope_frame_count = 0; 1885 } 1886 ch.vibrato_note_offset = 0.0f; 1887 ch.tremolo_volume = 0.0f; 1888 ch.tremor_on = false; 1889 1890 ch.autovibrato_ticks = 0; 1891 1892 if(ch.vibrato_waveform_retrigger) { 1893 ch.vibrato_ticks = 0; /* XXX: should the waveform itself also 1894 * be reset to sine? */ 1895 } 1896 if(ch.tremolo_waveform_retrigger) { 1897 ch.tremolo_ticks = 0; 1898 } 1899 1900 if(!(flags & XM_TRIGGER_KEEP_PERIOD)) { 1901 ch.period = xm_period(ctx, ch.note); 1902 xm_update_frequency(ctx, ch); 1903 } 1904 1905 ch.latest_trigger = ctx.generated_samples; 1906 if(ch.instrument != null) { 1907 ch.instrument.latest_trigger = ctx.generated_samples; 1908 } 1909 if(ch.sample != null) { 1910 ch.sample.latest_trigger = ctx.generated_samples; 1911 } 1912 } 1913 1914 void xm_cut_note(xm_channel_context_t* ch) { 1915 /* NB: this is not the same as Key Off */ 1916 ch.volume = .0f; 1917 } 1918 1919 void xm_key_off(xm_channel_context_t* ch) { 1920 /* Key Off */ 1921 ch.sustained = false; 1922 1923 /* If no volume envelope is used, also cut the note */ 1924 if(ch.instrument == null || !ch.instrument.volume_envelope.enabled) { 1925 xm_cut_note(ch); 1926 } 1927 } 1928 1929 void xm_row(xm_context_t* ctx) { 1930 if(ctx.position_jump) { 1931 ctx.current_table_index = ctx.jump_dest; 1932 ctx.current_row = ctx.jump_row; 1933 ctx.position_jump = false; 1934 ctx.pattern_break = false; 1935 ctx.jump_row = 0; 1936 xm_post_pattern_change(ctx); 1937 } else if(ctx.pattern_break) { 1938 ctx.current_table_index++; 1939 ctx.current_row = ctx.jump_row; 1940 ctx.pattern_break = false; 1941 ctx.jump_row = 0; 1942 xm_post_pattern_change(ctx); 1943 } 1944 1945 xm_pattern_t* cur = ctx.module_.patterns + ctx.module_.pattern_table[ctx.current_table_index]; 1946 bool in_a_loop = false; 1947 1948 /* Read notes… */ 1949 for(uint8_t i = 0; i < ctx.module_.num_channels; ++i) { 1950 xm_pattern_slot_t* s = cur.slots + ctx.current_row * ctx.module_.num_channels + i; 1951 xm_channel_context_t* ch = ctx.channels + i; 1952 1953 ch.current = s; 1954 1955 if(s.effect_type != 0xE || s.effect_param >> 4 != 0xD) { 1956 xm_handle_note_and_instrument(ctx, ch, s); 1957 } else { 1958 ch.note_delay_param = s.effect_param & 0x0F; 1959 } 1960 1961 if(!in_a_loop && ch.pattern_loop_count > 0) { 1962 in_a_loop = true; 1963 } 1964 } 1965 1966 if(!in_a_loop) { 1967 /* No E6y loop is in effect (or we are in the first pass) */ 1968 ctx.loop_count = (ctx.row_loop_count[MAX_NUM_ROWS * ctx.current_table_index + ctx.current_row]++); 1969 } 1970 1971 ctx.current_row++; /* Since this is an uint8, this line can 1972 * increment from 255 to 0, in which case it 1973 * is still necessary to go the next 1974 * pattern. */ 1975 if(!ctx.position_jump && !ctx.pattern_break && 1976 (ctx.current_row >= cur.num_rows || ctx.current_row == 0)) { 1977 ctx.current_table_index++; 1978 ctx.current_row = ctx.jump_row; /* This will be 0 most of 1979 * the time, except when E60 1980 * is used */ 1981 ctx.jump_row = 0; 1982 xm_post_pattern_change(ctx); 1983 } 1984 } 1985 1986 void xm_envelope_tick(xm_channel_context_t* ch, 1987 xm_envelope_t* env, 1988 uint16_t* counter, 1989 float* outval) { 1990 if(env.num_points < 2) { 1991 /* Don't really know what to do… */ 1992 if(env.num_points == 1) { 1993 /* XXX I am pulling this out of my ass */ 1994 *outval = cast(float)env.points[0].value / cast(float)0x40; 1995 if(*outval > 1) { 1996 *outval = 1; 1997 } 1998 } 1999 2000 return; 2001 } else { 2002 uint8_t j; 2003 2004 if(env.loop_enabled) { 2005 uint16_t loop_start = env.points[env.loop_start_point].frame; 2006 uint16_t loop_end = env.points[env.loop_end_point].frame; 2007 uint16_t loop_length = cast(ushort)(loop_end - loop_start); 2008 2009 if(*counter >= loop_end) { 2010 *counter -= loop_length; 2011 } 2012 } 2013 2014 for(j = 0; j < (env.num_points - 2); ++j) { 2015 if(env.points[j].frame <= *counter && 2016 env.points[j+1].frame >= *counter) { 2017 break; 2018 } 2019 } 2020 2021 *outval = xm_envelope_lerp(env.points.ptr + j, env.points.ptr + j + 1, *counter) / cast(float)0x40; 2022 2023 /* Make sure it is safe to increment frame count */ 2024 if(!ch.sustained || !env.sustain_enabled || 2025 *counter != env.points[env.sustain_point].frame) { 2026 (*counter)++; 2027 } 2028 } 2029 } 2030 2031 void xm_envelopes(xm_channel_context_t* ch) { 2032 if(ch.instrument != null) { 2033 if(ch.instrument.volume_envelope.enabled) { 2034 if(!ch.sustained) { 2035 ch.fadeout_volume -= ch.instrument.volume_fadeout / 32768.0f; 2036 if(ch.fadeout_volume < 0) ch.fadeout_volume = 0; 2037 } 2038 2039 xm_envelope_tick(ch, 2040 &(ch.instrument.volume_envelope), 2041 &(ch.volume_envelope_frame_count), 2042 &(ch.volume_envelope_volume)); 2043 } 2044 2045 if(ch.instrument.panning_envelope.enabled) { 2046 xm_envelope_tick(ch, 2047 &(ch.instrument.panning_envelope), 2048 &(ch.panning_envelope_frame_count), 2049 &(ch.panning_envelope_panning)); 2050 } 2051 } 2052 } 2053 2054 void xm_tick(xm_context_t* ctx) { 2055 if(ctx.current_tick == 0) { 2056 xm_row(ctx); 2057 } 2058 2059 for(uint8_t i = 0; i < ctx.module_.num_channels; ++i) { 2060 xm_channel_context_t* ch = ctx.channels + i; 2061 2062 xm_envelopes(ch); 2063 xm_autovibrato(ctx, ch); 2064 2065 if(ch.arp_in_progress && !ch.current.HAS_ARPEGGIO()) { 2066 ch.arp_in_progress = false; 2067 ch.arp_note_offset = 0; 2068 xm_update_frequency(ctx, ch); 2069 } 2070 if(ch.vibrato_in_progress && !ch.current.HAS_VIBRATO()) { 2071 ch.vibrato_in_progress = false; 2072 ch.vibrato_note_offset = 0.0f; 2073 xm_update_frequency(ctx, ch); 2074 } 2075 2076 switch(ch.current.volume_column >> 4) { 2077 2078 case 0x6: /* Volume slide down */ 2079 if(ctx.current_tick == 0) break; 2080 xm_volume_slide(ch, ch.current.volume_column & 0x0F); 2081 break; 2082 2083 case 0x7: /* Volume slide up */ 2084 if(ctx.current_tick == 0) break; 2085 xm_volume_slide(ch, cast(ubyte)(ch.current.volume_column << 4)); 2086 break; 2087 2088 case 0xB: /* Vibrato */ 2089 if(ctx.current_tick == 0) break; 2090 ch.vibrato_in_progress = false; 2091 xm_vibrato(ctx, ch, ch.vibrato_param); 2092 break; 2093 2094 case 0xD: /* Panning slide left */ 2095 if(ctx.current_tick == 0) break; 2096 xm_panning_slide(ch, ch.current.volume_column & 0x0F); 2097 break; 2098 2099 case 0xE: /* Panning slide right */ 2100 if(ctx.current_tick == 0) break; 2101 xm_panning_slide(ch, cast(ubyte)(ch.current.volume_column << 4)); 2102 break; 2103 2104 case 0xF: /* Tone portamento */ 2105 if(ctx.current_tick == 0) break; 2106 xm_tone_portamento(ctx, ch); 2107 break; 2108 2109 default: 2110 break; 2111 2112 } 2113 2114 switch(ch.current.effect_type) { 2115 2116 case 0: /* 0xy: Arpeggio */ 2117 if(ch.current.effect_param > 0) { 2118 char arp_offset = ctx.tempo % 3; 2119 switch(arp_offset) { 2120 case 2: /* 0 . x . 0 . y . x . … */ 2121 if(ctx.current_tick == 1) { 2122 ch.arp_in_progress = true; 2123 ch.arp_note_offset = ch.current.effect_param >> 4; 2124 xm_update_frequency(ctx, ch); 2125 break; 2126 } 2127 /* No break here, this is intended */ 2128 goto case 1; 2129 2130 case 1: /* 0 . 0 . y . x . … */ 2131 if(ctx.current_tick == 0) 2132 { 2133 ch.arp_in_progress = false; 2134 ch.arp_note_offset = 0; 2135 xm_update_frequency(ctx, ch); 2136 break; 2137 } 2138 /* No break here, this is intended */ 2139 goto case 0; 2140 2141 case 0: /* 0 . y . x . … */ 2142 xm_arpeggio(ctx, ch, ch.current.effect_param, cast(ushort)(ctx.current_tick - arp_offset)); 2143 break; 2144 2145 default: 2146 break; 2147 } 2148 } 2149 break; 2150 2151 case 1: /* 1xx: Portamento up */ 2152 if(ctx.current_tick == 0) break; 2153 xm_pitch_slide(ctx, ch, -cast(int)ch.portamento_up_param); 2154 break; 2155 2156 case 2: /* 2xx: Portamento down */ 2157 if(ctx.current_tick == 0) break; 2158 xm_pitch_slide(ctx, ch, ch.portamento_down_param); 2159 break; 2160 2161 case 3: /* 3xx: Tone portamento */ 2162 if(ctx.current_tick == 0) break; 2163 xm_tone_portamento(ctx, ch); 2164 break; 2165 2166 case 4: /* 4xy: Vibrato */ 2167 if(ctx.current_tick == 0) break; 2168 ch.vibrato_in_progress = true; 2169 xm_vibrato(ctx, ch, ch.vibrato_param); 2170 break; 2171 2172 case 5: /* 5xy: Tone portamento + Volume slide */ 2173 if(ctx.current_tick == 0) break; 2174 xm_tone_portamento(ctx, ch); 2175 xm_volume_slide(ch, ch.volume_slide_param); 2176 break; 2177 2178 case 6: /* 6xy: Vibrato + Volume slide */ 2179 if(ctx.current_tick == 0) break; 2180 ch.vibrato_in_progress = true; 2181 xm_vibrato(ctx, ch, ch.vibrato_param); 2182 xm_volume_slide(ch, ch.volume_slide_param); 2183 break; 2184 2185 case 7: /* 7xy: Tremolo */ 2186 if(ctx.current_tick == 0) break; 2187 xm_tremolo(ctx, ch, ch.tremolo_param, ch.tremolo_ticks++); 2188 break; 2189 2190 case 0xA: /* Axy: Volume slide */ 2191 if(ctx.current_tick == 0) break; 2192 xm_volume_slide(ch, ch.volume_slide_param); 2193 break; 2194 2195 case 0xE: /* EXy: Extended command */ 2196 switch(ch.current.effect_param >> 4) { 2197 2198 case 0x9: /* E9y: Retrigger note */ 2199 if(ctx.current_tick != 0 && ch.current.effect_param & 0x0F) { 2200 if(!(ctx.current_tick % (ch.current.effect_param & 0x0F))) { 2201 xm_trigger_note(ctx, ch, XM_TRIGGER_KEEP_VOLUME); 2202 xm_envelopes(ch); 2203 } 2204 } 2205 break; 2206 2207 case 0xC: /* ECy: Note cut */ 2208 if((ch.current.effect_param & 0x0F) == ctx.current_tick) { 2209 xm_cut_note(ch); 2210 } 2211 break; 2212 2213 case 0xD: /* EDy: Note delay */ 2214 if(ch.note_delay_param == ctx.current_tick) { 2215 xm_handle_note_and_instrument(ctx, ch, ch.current); 2216 xm_envelopes(ch); 2217 } 2218 break; 2219 2220 default: 2221 break; 2222 2223 } 2224 break; 2225 2226 case 17: /* Hxy: Global volume slide */ 2227 if(ctx.current_tick == 0) break; 2228 if((ch.global_volume_slide_param & 0xF0) && 2229 (ch.global_volume_slide_param & 0x0F)) { 2230 /* Illegal state */ 2231 break; 2232 } 2233 if(ch.global_volume_slide_param & 0xF0) { 2234 /* Global slide up */ 2235 float f = cast(float)(ch.global_volume_slide_param >> 4) / cast(float)0x40; 2236 ctx.global_volume += f; 2237 if(ctx.global_volume > 1) 2238 ctx.global_volume = 1; 2239 } else { 2240 /* Global slide down */ 2241 float f = cast(float)(ch.global_volume_slide_param & 0x0F) / cast(float)0x40; 2242 ctx.global_volume -= f; 2243 if (ctx.global_volume < 0) 2244 ctx.global_volume = 0; 2245 } 2246 break; 2247 2248 case 20: /* Kxx: Key off */ 2249 /* Most documentations will tell you the parameter has no 2250 * use. Don't be fooled. */ 2251 if(ctx.current_tick == ch.current.effect_param) { 2252 xm_key_off(ch); 2253 } 2254 break; 2255 2256 case 25: /* Pxy: Panning slide */ 2257 if(ctx.current_tick == 0) break; 2258 xm_panning_slide(ch, ch.panning_slide_param); 2259 break; 2260 2261 case 27: /* Rxy: Multi retrig note */ 2262 if(ctx.current_tick == 0) break; 2263 if(((ch.multi_retrig_param) & 0x0F) == 0) break; 2264 if((ctx.current_tick % (ch.multi_retrig_param & 0x0F)) == 0) { 2265 xm_trigger_note(ctx, ch, XM_TRIGGER_KEEP_VOLUME | XM_TRIGGER_KEEP_ENVELOPE); 2266 2267 /* Rxy doesn't affect volume if there's a command in the volume 2268 column, or if the instrument has a volume envelope. */ 2269 if (!ch.current.volume_column && !ch.instrument.volume_envelope.enabled){ 2270 float v = ch.volume * multi_retrig_multiply[ch.multi_retrig_param >> 4] 2271 + multi_retrig_add[ch.multi_retrig_param >> 4] / cast(float)0x40; 2272 if (v < 0) v = 0; 2273 if (v > 1) v = 1; 2274 ch.volume = v; 2275 } 2276 } 2277 break; 2278 2279 case 29: /* Txy: Tremor */ 2280 if(ctx.current_tick == 0) break; 2281 ch.tremor_on = ( 2282 (ctx.current_tick - 1) % ((ch.tremor_param >> 4) + (ch.tremor_param & 0x0F) + 2) 2283 > 2284 (ch.tremor_param >> 4) 2285 ); 2286 break; 2287 2288 default: 2289 break; 2290 2291 } 2292 2293 float panning, volume; 2294 2295 panning = ch.panning + 2296 (ch.panning_envelope_panning - .5f) * (.5f - fast_fabs(ch.panning - .5f)) * 2.0f; 2297 2298 if(ch.tremor_on) { 2299 volume = .0f; 2300 } else { 2301 volume = ch.volume + ch.tremolo_volume; 2302 if (volume < 0) volume = 0; 2303 if (volume > 1) volume = 1; 2304 volume *= ch.fadeout_volume * ch.volume_envelope_volume; 2305 } 2306 2307 version(XM_RAMPING) 2308 { 2309 /* See https://modarchive.org/forums/index.php?topic=3517.0 2310 * and https://github.com/Artefact2/libxm/pull/16 */ 2311 ch.target_volume[0] = volume * fast_sqrt(1.0f - panning); 2312 ch.target_volume[1] = volume * fast_sqrt(panning); 2313 } 2314 else 2315 { 2316 ch.actual_volume[0] = volume * fast_sqrt(1.0f - panning); 2317 ch.actual_volume[1] = volume * fast_sqrt(panning); 2318 } 2319 } 2320 2321 ctx.current_tick++; 2322 if(ctx.current_tick >= ctx.tempo + ctx.extra_ticks) { 2323 ctx.current_tick = 0; 2324 ctx.extra_ticks = 0; 2325 } 2326 2327 /* FT2 manual says number of ticks / second = BPM * 0.4 */ 2328 ctx.remaining_samples_in_tick += cast(float)ctx.rate / (cast(float)ctx.bpm * 0.4f); 2329 } 2330 2331 float xm_sample_at(xm_sample_t* sample, size_t k) { 2332 return sample.bits == 8 ? (sample.data8[k] / 128.0f) : (sample.data16[k] / 32768.0f); 2333 } 2334 2335 float xm_next_of_sample(xm_channel_context_t* ch) { 2336 if(ch.instrument == null || ch.sample == null || ch.sample_position < 0) { 2337 version(XM_RAMPING) 2338 { 2339 if(ch.frame_count < XM_SAMPLE_RAMPING_POINTS) { 2340 return XM_LERP(ch.end_of_previous_sample[ch.frame_count], .0f, 2341 cast(float)ch.frame_count / cast(float)XM_SAMPLE_RAMPING_POINTS); 2342 } 2343 } 2344 return .0f; 2345 } 2346 if(ch.sample.length == 0) { 2347 return .0f; 2348 } 2349 2350 float u, v, t; 2351 uint32_t a, b; 2352 a = cast(uint32_t)ch.sample_position; /* This cast is fine, 2353 * sample_position will not 2354 * go above integer 2355 * ranges */ 2356 if(XM_LINEAR_INTERPOLATION) { 2357 b = a + 1; 2358 t = ch.sample_position - a; 2359 } 2360 u = xm_sample_at(ch.sample, a); 2361 2362 switch(ch.sample.loop_type) { 2363 2364 case XM_NO_LOOP: 2365 if(XM_LINEAR_INTERPOLATION) { 2366 v = (b < ch.sample.length) ? xm_sample_at(ch.sample, b) : .0f; 2367 } 2368 ch.sample_position += ch.step; 2369 if(ch.sample_position >= ch.sample.length) { 2370 ch.sample_position = -1; 2371 } 2372 break; 2373 2374 case XM_FORWARD_LOOP: 2375 if(XM_LINEAR_INTERPOLATION) { 2376 v = xm_sample_at( 2377 ch.sample, 2378 (b == ch.sample.loop_end) ? ch.sample.loop_start : b 2379 ); 2380 } 2381 ch.sample_position += ch.step; 2382 while(ch.sample_position >= ch.sample.loop_end) { 2383 ch.sample_position -= ch.sample.loop_length; 2384 } 2385 break; 2386 2387 case XM_PING_PONG_LOOP: 2388 if(ch.ping) { 2389 ch.sample_position += ch.step; 2390 } else { 2391 ch.sample_position -= ch.step; 2392 } 2393 /* XXX: this may not work for very tight ping-pong loops 2394 * (ie switches direction more than once per sample */ 2395 if(ch.ping) { 2396 if(XM_LINEAR_INTERPOLATION) { 2397 v = xm_sample_at(ch.sample, (b >= ch.sample.loop_end) ? a : b); 2398 } 2399 if(ch.sample_position >= ch.sample.loop_end) { 2400 ch.ping = false; 2401 ch.sample_position = (ch.sample.loop_end << 1) - ch.sample_position; 2402 } 2403 /* sanity checking */ 2404 if(ch.sample_position >= ch.sample.length) { 2405 ch.ping = false; 2406 ch.sample_position -= ch.sample.length - 1; 2407 } 2408 } else { 2409 if(XM_LINEAR_INTERPOLATION) { 2410 v = u; 2411 u = xm_sample_at( 2412 ch.sample, 2413 (b == 1 || b - 2 <= ch.sample.loop_start) ? a : (b - 2) 2414 ); 2415 } 2416 if(ch.sample_position <= ch.sample.loop_start) { 2417 ch.ping = true; 2418 ch.sample_position = (ch.sample.loop_start << 1) - ch.sample_position; 2419 } 2420 /* sanity checking */ 2421 if(ch.sample_position <= .0f) { 2422 ch.ping = true; 2423 ch.sample_position = .0f; 2424 } 2425 } 2426 break; 2427 2428 default: 2429 v = .0f; 2430 break; 2431 } 2432 2433 float endval = (XM_LINEAR_INTERPOLATION ? XM_LERP(u, v, t) : u); 2434 2435 version(XM_RAMPING) 2436 { 2437 if(ch.frame_count < XM_SAMPLE_RAMPING_POINTS) { 2438 /* Smoothly transition between old and new sample. */ 2439 return XM_LERP(ch.end_of_previous_sample[ch.frame_count], endval, 2440 cast(float)ch.frame_count / cast(float)XM_SAMPLE_RAMPING_POINTS); 2441 } 2442 } 2443 2444 return endval; 2445 } 2446 2447 void xm_sample(xm_context_t* ctx, float* left, float* right) { 2448 if(ctx.remaining_samples_in_tick <= 0) { 2449 xm_tick(ctx); 2450 } 2451 ctx.remaining_samples_in_tick--; 2452 2453 *left = 0.0f; 2454 *right = 0.0f; 2455 2456 if(ctx.max_loop_count > 0 && ctx.loop_count >= ctx.max_loop_count) { 2457 return; 2458 } 2459 2460 for(uint8_t i = 0; i < ctx.module_.num_channels; ++i) { 2461 xm_channel_context_t* ch = ctx.channels + i; 2462 2463 if(ch.instrument == null || ch.sample == null || ch.sample_position < 0) { 2464 continue; 2465 } 2466 2467 const float fval = xm_next_of_sample(ch); 2468 2469 if(!ch.muted && !ch.instrument.muted) { 2470 *left += fval * ch.actual_volume[0]; 2471 *right += fval * ch.actual_volume[1]; 2472 } 2473 2474 version(XM_RAMPING) 2475 { 2476 ch.frame_count++; 2477 XM_SLIDE_TOWARDS(ch.actual_volume[0], ch.target_volume[0], ctx.volume_ramp); 2478 XM_SLIDE_TOWARDS(ch.actual_volume[1], ch.target_volume[1], ctx.volume_ramp); 2479 } 2480 } 2481 2482 const float fgvol = ctx.global_volume * ctx.amplification; 2483 *left *= fgvol; 2484 *right *= fgvol; 2485 2486 /*if(XM_DEBUG) { 2487 if(fast_fabs(*left) > 1 || fast_fabs(*right) > 1) 2488 { 2489 assert(false); 2490 //DEBUG("clipping frame: %f %f, this is a bad module or a libxm bug", *left, *right); 2491 } 2492 }*/ 2493 } 2494 2495 void xm_generate_samples(xm_context_t* ctx, float* output, size_t numsamples) { 2496 ctx.generated_samples += numsamples; 2497 2498 for(size_t i = 0; i < numsamples; i++) { 2499 xm_sample(ctx, output + (2 * i), output + (2 * i + 1)); 2500 } 2501 }