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