1 /////////////////////////////////////////////////////////////////////////////////// 2 //-------------------------------------------------------------------------------// 3 //-------------------------------------------------------------------------------// 4 //-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------// 5 //----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------// 6 //---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------// 7 //--------H----H----X--X----C----------2-------0----0---0----0-----1-------------// 8 //-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------// 9 //-------------------------------------------------------------------------------// 10 //----------------------------------------------------- http://hxc2001.free.fr --// 11 /////////////////////////////////////////////////////////////////////////////////// 12 // File : hxcmod.c 13 // Contains: a tiny mod player 14 // 15 // Written by: Jean Francois DEL NERO 16 // 17 // You are free to do what you want with this code. 18 // A credit is always appreciated if you include it into your prod :) 19 // 20 // This file include some parts of the Noisetracker/Soundtracker/Protracker 21 // Module Format documentation written by Andrew Scott (Adrenalin Software) 22 // (modformat.txt) 23 // 24 // The core (hxcmod.c/hxcmod.h) is designed to have the least external dependency. 25 // So it should be usable on almost all OS and systems. 26 // Please also note that no dynamic allocation is done into the HxCMOD core. 27 // 28 // Change History (most recent first): 29 /////////////////////////////////////////////////////////////////////////////////// 30 // HxCMOD Core API: 31 // ------------------------------------------- 32 // int hxcmod_init(modcontext * modctx) 33 // 34 // - Initialize the modcontext buffer. Must be called before doing anything else. 35 // Return 1 if success. 0 in case of error. 36 // ------------------------------------------- 37 // int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size ) 38 // 39 // - "Load" a MOD from memory (from "mod_data" with size "mod_data_size"). 40 // Return 1 if success. 0 in case of error. 41 // ------------------------------------------- 42 // void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, unsigned long nbsample, tracker_buffer_state * trkbuf ) 43 // 44 // - Generate and return the next samples chunk to outbuffer. 45 // nbsample specify the number of stereo 16bits samples you want. 46 // The output format is signed 44100Hz 16-bit Stereo PCM samples. 47 // The output buffer size in byte must be equal to ( nbsample * 2 * 2 ). 48 // The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused. 49 // ------------------------------------------- 50 // void hxcmod_unload( modcontext * modctx ) 51 // - "Unload" / clear the player status. 52 // ------------------------------------------- 53 /////////////////////////////////////////////////////////////////////////////////// 54 55 #include "hxcmod.h" 56 57 /////////////////////////////////////////////////////////////////////////////////// 58 59 // Effects list 60 #define EFFECT_ARPEGGIO 0x0 // Supported 61 #define EFFECT_PORTAMENTO_UP 0x1 // Supported 62 #define EFFECT_PORTAMENTO_DOWN 0x2 // Supported 63 #define EFFECT_TONE_PORTAMENTO 0x3 // Supported 64 #define EFFECT_VIBRATO 0x4 // Supported 65 #define EFFECT_VOLSLIDE_TONEPORTA 0x5 // Supported 66 #define EFFECT_VOLSLIDE_VIBRATO 0x6 // Supported 67 #define EFFECT_VOLSLIDE_TREMOLO 0x7 // - TO BE DONE - 68 #define EFFECT_SET_PANNING 0x8 // - TO BE DONE - 69 #define EFFECT_SET_OFFSET 0x9 // Supported 70 #define EFFECT_VOLUME_SLIDE 0xA // Supported 71 #define EFFECT_JUMP_POSITION 0xB // Supported 72 #define EFFECT_SET_VOLUME 0xC // Supported 73 #define EFFECT_PATTERN_BREAK 0xD // Supported 74 75 #define EFFECT_EXTENDED 0xE 76 #define EFFECT_E_FINE_PORTA_UP 0x1 // Supported 77 #define EFFECT_E_FINE_PORTA_DOWN 0x2 // Supported 78 #define EFFECT_E_GLISSANDO_CTRL 0x3 // - TO BE DONE - 79 #define EFFECT_E_VIBRATO_WAVEFORM 0x4 // - TO BE DONE - 80 #define EFFECT_E_SET_FINETUNE 0x5 // - TO BE DONE - 81 #define EFFECT_E_PATTERN_LOOP 0x6 // Supported 82 #define EFFECT_E_TREMOLO_WAVEFORM 0x7 // - TO BE DONE - 83 #define EFFECT_E_SET_PANNING_2 0x8 // - TO BE DONE - 84 #define EFFECT_E_RETRIGGER_NOTE 0x9 // - TO BE DONE - 85 #define EFFECT_E_FINE_VOLSLIDE_UP 0xA // Supported 86 #define EFFECT_E_FINE_VOLSLIDE_DOWN 0xB // Supported 87 #define EFFECT_E_NOTE_CUT 0xC // Supported 88 #define EFFECT_E_NOTE_DELAY 0xD // - TO BE DONE - 89 #define EFFECT_E_PATTERN_DELAY 0xE // Supported 90 #define EFFECT_E_INVERT_LOOP 0xF // - TO BE DONE - 91 #define EFFECT_SET_SPEED 0xF0 // Supported 92 #define EFFECT_SET_TEMPO 0xF2 // Supported 93 94 #define PERIOD_TABLE_LENGTH MAXNOTES 95 #define FULL_PERIOD_TABLE_LENGTH ( PERIOD_TABLE_LENGTH * 8 ) 96 97 static void memcopy( void * dest, void *source, unsigned long size ); 98 99 static const short periodtable[]= 100 { 101 27392, 25856, 24384, 23040, 21696, 20480, 19328, 18240, 17216, 16256, 15360, 14496, 102 13696, 12928, 12192, 11520, 10848, 10240, 9664, 9120, 8606, 8128, 7680, 7248, 103 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624, 104 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1812, 105 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906, 106 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453, 107 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 108 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113, 109 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56, 110 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28, 111 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14, 112 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7 113 }; 114 115 static const short sintable[]={ 116 0, 24, 49, 74, 97, 120, 141,161, 117 180, 197, 212, 224, 235, 244, 250,253, 118 255, 253, 250, 244, 235, 224, 212,197, 119 180, 161, 141, 120, 97, 74, 49, 24 120 }; 121 122 typedef struct modtype_ 123 { 124 unsigned char signature[5]; 125 int numberofchannels; 126 }modtype; 127 128 modtype modlist[]= 129 { 130 { "M!K!",4}, 131 { "M.K.",4}, 132 { "FLT4",4}, 133 { "FLT8",8}, 134 { "4CHN",4}, 135 { "6CHN",6}, 136 { "8CHN",8}, 137 { "10CH",10}, 138 { "12CH",12}, 139 { "14CH",14}, 140 { "16CH",16}, 141 { "18CH",18}, 142 { "20CH",20}, 143 { "22CH",22}, 144 { "24CH",24}, 145 { "26CH",26}, 146 { "28CH",28}, 147 { "30CH",30}, 148 { "32CH",32}, 149 { "",0} 150 }; 151 152 /////////////////////////////////////////////////////////////////////////////////// 153 154 static void memcopy( void * dest, void *source, unsigned long size ) 155 { 156 unsigned long i; 157 unsigned char * d,*s; 158 159 d=(unsigned char*)dest; 160 s=(unsigned char*)source; 161 for(i=0;i<size;i++) 162 { 163 d[i]=s[i]; 164 } 165 } 166 167 static void memclear( void * dest, unsigned char value, unsigned long size ) 168 { 169 unsigned long i; 170 unsigned char * d; 171 172 d=(unsigned char*)dest; 173 for(i=0;i<size;i++) 174 { 175 d[i]=value; 176 } 177 } 178 179 static int memcompare( unsigned char * buf1, unsigned char * buf2, unsigned int size ) 180 { 181 unsigned int i; 182 183 i = 0; 184 185 while(i<size) 186 { 187 if(buf1[i] != buf2[i]) 188 { 189 return 0; 190 } 191 i++; 192 } 193 194 return 1; 195 } 196 197 static int getnote( modcontext * mod, unsigned short period, int finetune ) 198 { 199 (void) finetune; 200 int i; 201 202 for(i = 0; i < FULL_PERIOD_TABLE_LENGTH; i++) 203 { 204 if(period >= mod->fullperiod[i]) 205 { 206 return i; 207 } 208 } 209 210 return MAXNOTES; 211 } 212 213 static void worknote( note * nptr, hxcmod_channel * cptr,char t,modcontext * mod ) 214 { 215 (void) t; 216 muint _sample, period, effect, operiod; 217 muint curnote, arpnote; 218 219 _sample = (nptr->sampperiod & 0xF0) | (nptr->sampeffect >> 4); 220 period = ((nptr->sampperiod & 0xF) << 8) | nptr->period; 221 effect = ((nptr->sampeffect & 0xF) << 8) | nptr->effect; 222 223 operiod = cptr->period; 224 225 if ( period || _sample ) 226 { 227 if( _sample && _sample<32 ) 228 { 229 cptr->sampnum = _sample - 1; 230 } 231 232 if( period || _sample ) 233 { 234 cptr->sampdata = mod->sampledata[cptr->sampnum]; 235 cptr->length = mod->song.samples[cptr->sampnum].length; 236 cptr->reppnt = mod->song.samples[cptr->sampnum].reppnt; 237 cptr->replen = mod->song.samples[cptr->sampnum].replen; 238 239 cptr->finetune = (mod->song.samples[cptr->sampnum].finetune)&0xF; 240 241 if(effect>>8!=4 && effect>>8!=6) 242 { 243 cptr->vibraperiod=0; 244 cptr->vibrapointeur=0; 245 } 246 } 247 248 if( (_sample != 0) && ( (effect>>8) != EFFECT_VOLSLIDE_TONEPORTA ) ) 249 { 250 cptr->volume = mod->song.samples[cptr->sampnum].volume; 251 cptr->volumeslide = 0; 252 } 253 254 if( ( (effect>>8) != EFFECT_TONE_PORTAMENTO && (effect>>8)!=EFFECT_VOLSLIDE_TONEPORTA) ) 255 { 256 if (period!=0) 257 cptr->samppos = 0; 258 } 259 260 cptr->decalperiod=0; 261 if( period ) 262 { 263 if(cptr->finetune) 264 { 265 if( cptr->finetune <= 7 ) 266 { 267 period = mod->fullperiod[getnote(mod,period,0) + cptr->finetune]; 268 } 269 else 270 { 271 period = mod->fullperiod[getnote(mod,period,0) - (16 - (cptr->finetune)) ]; 272 } 273 } 274 275 cptr->period = period; 276 } 277 278 } 279 280 cptr->effect = 0; 281 cptr->parameffect = 0; 282 cptr->effect_code = effect; 283 284 switch (effect >> 8) 285 { 286 case EFFECT_ARPEGGIO: 287 /* 288 [0]: Arpeggio 289 Where [0][x][y] means "play note, note+x semitones, note+y 290 semitones, then return to original note". The fluctuations are 291 carried out evenly spaced in one pattern division. They are usually 292 used to simulate chords, but this doesn't work too well. They are 293 also used to produce heavy vibrato. A major chord is when x=4, y=7. 294 A minor chord is when x=3, y=7. 295 */ 296 297 if(effect&0xff) 298 { 299 cptr->effect = EFFECT_ARPEGGIO; 300 cptr->parameffect = effect&0xff; 301 302 cptr->ArpIndex = 0; 303 304 curnote = getnote(mod,cptr->period,cptr->finetune); 305 306 cptr->Arpperiods[0] = cptr->period; 307 308 arpnote = curnote + (((cptr->parameffect>>4)&0xF)*8); 309 if( arpnote >= FULL_PERIOD_TABLE_LENGTH ) 310 arpnote = FULL_PERIOD_TABLE_LENGTH - 1; 311 312 cptr->Arpperiods[1] = mod->fullperiod[arpnote]; 313 314 arpnote = curnote + (((cptr->parameffect)&0xF)*8); 315 if( arpnote >= FULL_PERIOD_TABLE_LENGTH ) 316 arpnote = FULL_PERIOD_TABLE_LENGTH - 1; 317 318 cptr->Arpperiods[2] = mod->fullperiod[arpnote]; 319 } 320 break; 321 322 case EFFECT_PORTAMENTO_UP: 323 /* 324 [1]: Slide up 325 Where [1][x][y] means "smoothly decrease the period of current 326 sample by x*16+y after each tick in the division". The 327 ticks/division are set with the 'set speed' effect (see below). If 328 the period of the note being played is z, then the final period 329 will be z - (x*16 + y)*(ticks - 1). As the slide rate depends on 330 the speed, changing the speed will change the slide. You cannot 331 slide beyond the note B3 (period 113). 332 */ 333 334 cptr->effect = EFFECT_PORTAMENTO_UP; 335 cptr->parameffect = effect&0xff; 336 break; 337 338 case EFFECT_PORTAMENTO_DOWN: 339 /* 340 [2]: Slide down 341 Where [2][x][y] means "smoothly increase the period of current 342 sample by x*16+y after each tick in the division". Similar to [1], 343 but lowers the pitch. You cannot slide beyond the note C1 (period 344 856). 345 */ 346 347 cptr->effect = EFFECT_PORTAMENTO_DOWN; 348 cptr->parameffect = effect&0xff; 349 break; 350 351 case EFFECT_TONE_PORTAMENTO: 352 /* 353 [3]: Slide to note 354 Where [3][x][y] means "smoothly change the period of current sample 355 by x*16+y after each tick in the division, never sliding beyond 356 current period". The period-length in this channel's division is a 357 parameter to this effect, and hence is not played. Sliding to a 358 note is similar to effects [1] and [2], but the slide will not go 359 beyond the given period, and the direction is implied by that 360 period. If x and y are both 0, then the old slide will continue. 361 */ 362 363 cptr->effect = EFFECT_TONE_PORTAMENTO; 364 if( (effect&0xff) != 0 ) 365 { 366 cptr->portaspeed = (short)(effect&0xff); 367 } 368 369 if(period!=0) 370 { 371 cptr->portaperiod = period; 372 cptr->period = operiod; 373 } 374 break; 375 376 case EFFECT_VIBRATO: 377 /* 378 [4]: Vibrato 379 Where [4][x][y] means "oscillate the sample pitch using a 380 particular waveform with amplitude y/16 semitones, such that (x * 381 ticks)/64 cycles occur in the division". The waveform is set using 382 effect [14][4]. By placing vibrato effects on consecutive 383 divisions, the vibrato effect can be maintained. If either x or y 384 are 0, then the old vibrato values will be used. 385 */ 386 387 cptr->effect = EFFECT_VIBRATO; 388 if( ( effect & 0x0F ) != 0 ) // Depth continue or change ? 389 cptr->vibraparam = (cptr->vibraparam & 0xF0) | ( effect & 0x0F ); 390 if( ( effect & 0xF0 ) != 0 ) // Speed continue or change ? 391 cptr->vibraparam = (cptr->vibraparam & 0x0F) | ( effect & 0xF0 ); 392 393 break; 394 395 case EFFECT_VOLSLIDE_TONEPORTA: 396 /* 397 [5]: Continue 'Slide to note', but also do Volume slide 398 Where [5][x][y] means "either slide the volume up x*(ticks - 1) or 399 slide the volume down y*(ticks - 1), at the same time as continuing 400 the last 'Slide to note'". It is illegal for both x and y to be 401 non-zero. You cannot slide outside the volume range 0..64. The 402 period-length in this channel's division is a parameter to this 403 effect, and hence is not played. 404 */ 405 406 if( period != 0 ) 407 { 408 cptr->portaperiod = period; 409 cptr->period = operiod; 410 } 411 412 cptr->effect = EFFECT_VOLSLIDE_TONEPORTA; 413 if( ( effect & 0xFF ) != 0 ) 414 cptr->volumeslide = ( effect & 0xFF ); 415 416 break; 417 418 case EFFECT_VOLSLIDE_VIBRATO: 419 /* 420 [6]: Continue 'Vibrato', but also do Volume slide 421 Where [6][x][y] means "either slide the volume up x*(ticks - 1) or 422 slide the volume down y*(ticks - 1), at the same time as continuing 423 the last 'Vibrato'". It is illegal for both x and y to be non-zero. 424 You cannot slide outside the volume range 0..64. 425 */ 426 427 cptr->effect = EFFECT_VOLSLIDE_VIBRATO; 428 if( (effect & 0xFF) != 0 ) 429 cptr->volumeslide = (effect & 0xFF); 430 break; 431 432 case EFFECT_SET_OFFSET: 433 /* 434 [9]: Set sample offset 435 Where [9][x][y] means "play the sample from offset x*4096 + y*256". 436 The offset is measured in words. If no sample is given, yet one is 437 still playing on this channel, it should be retriggered to the new 438 offset using the current volume. 439 */ 440 441 cptr->samppos = ((effect>>4) * 4096) + ((effect&0xF)*256); 442 443 break; 444 445 case EFFECT_VOLUME_SLIDE: 446 /* 447 [10]: Volume slide 448 Where [10][x][y] means "either slide the volume up x*(ticks - 1) or 449 slide the volume down y*(ticks - 1)". If both x and y are non-zero, 450 then the y value is ignored (assumed to be 0). You cannot slide 451 outside the volume range 0..64. 452 */ 453 454 cptr->effect = EFFECT_VOLUME_SLIDE; 455 cptr->volumeslide = (effect & 0xFF); 456 break; 457 458 case EFFECT_JUMP_POSITION: 459 /* 460 [11]: Position Jump 461 Where [11][x][y] means "stop the pattern after this division, and 462 continue the song at song-position x*16+y". This shifts the 463 'pattern-cursor' in the pattern table (see above). Legal values for 464 x*16+y are from 0 to 127. 465 */ 466 467 mod->tablepos = (effect & 0xFF); 468 if(mod->tablepos >= mod->song.length) 469 mod->tablepos = 0; 470 mod->patternpos = 0; 471 mod->jump_loop_effect = 1; 472 473 break; 474 475 case EFFECT_SET_VOLUME: 476 /* 477 [12]: Set volume 478 Where [12][x][y] means "set current sample's volume to x*16+y". 479 Legal volumes are 0..64. 480 */ 481 482 cptr->volume = (effect & 0xFF); 483 break; 484 485 case EFFECT_PATTERN_BREAK: 486 /* 487 [13]: Pattern Break 488 Where [13][x][y] means "stop the pattern after this division, and 489 continue the song at the next pattern at division x*10+y" (the 10 490 is not a typo). Legal divisions are from 0 to 63 (note Protracker 491 exception above). 492 */ 493 494 mod->patternpos = ( ((effect>>4)&0xF)*10 + (effect&0xF) ) * mod->number_of_channels; 495 mod->jump_loop_effect = 1; 496 mod->tablepos++; 497 if(mod->tablepos >= mod->song.length) 498 mod->tablepos = 0; 499 500 break; 501 502 case EFFECT_EXTENDED: 503 switch( (effect>>4) & 0xF ) 504 { 505 case EFFECT_E_FINE_PORTA_UP: 506 /* 507 [14][1]: Fineslide up 508 Where [14][1][x] means "decrement the period of the current sample 509 by x". The incrementing takes place at the beginning of the 510 division, and hence there is no actual sliding. You cannot slide 511 beyond the note B3 (period 113). 512 */ 513 514 cptr->period -= (effect & 0xF); 515 if( cptr->period < 113 ) 516 cptr->period = 113; 517 break; 518 519 case EFFECT_E_FINE_PORTA_DOWN: 520 /* 521 [14][2]: Fineslide down 522 Where [14][2][x] means "increment the period of the current sample 523 by x". Similar to [14][1] but shifts the pitch down. You cannot 524 slide beyond the note C1 (period 856). 525 */ 526 527 cptr->period += (effect & 0xF); 528 if( cptr->period > 856 ) 529 cptr->period = 856; 530 break; 531 532 case EFFECT_E_FINE_VOLSLIDE_UP: 533 /* 534 [14][10]: Fine volume slide up 535 Where [14][10][x] means "increment the volume of the current sample 536 by x". The incrementing takes place at the beginning of the 537 division, and hence there is no sliding. You cannot slide beyond 538 volume 64. 539 */ 540 541 cptr->volume += (effect & 0xF); 542 if( cptr->volume>64 ) 543 cptr->volume = 64; 544 break; 545 546 case EFFECT_E_FINE_VOLSLIDE_DOWN: 547 /* 548 [14][11]: Fine volume slide down 549 Where [14][11][x] means "decrement the volume of the current sample 550 by x". Similar to [14][10] but lowers volume. You cannot slide 551 beyond volume 0. 552 */ 553 554 cptr->volume -= (effect & 0xF); 555 if( cptr->volume > 200 ) 556 cptr->volume = 0; 557 break; 558 559 case EFFECT_E_PATTERN_LOOP: 560 /* 561 [14][6]: Loop pattern 562 Where [14][6][x] means "set the start of a loop to this division if 563 x is 0, otherwise after this division, jump back to the start of a 564 loop and play it another x times before continuing". If the start 565 of the loop was not set, it will default to the start of the 566 current pattern. Hence 'loop pattern' cannot be performed across 567 multiple patterns. Note that loops do not support nesting, and you 568 may generate an infinite loop if you try to nest 'loop pattern's. 569 */ 570 571 if( effect & 0xF ) 572 { 573 if( cptr->patternloopcnt ) 574 { 575 cptr->patternloopcnt--; 576 if( cptr->patternloopcnt ) 577 { 578 mod->patternpos = cptr->patternloopstartpoint; 579 mod->jump_loop_effect = 1; 580 } 581 else 582 { 583 cptr->patternloopstartpoint = mod->patternpos ; 584 } 585 } 586 else 587 { 588 cptr->patternloopcnt = (effect & 0xF); 589 mod->patternpos = cptr->patternloopstartpoint; 590 mod->jump_loop_effect = 1; 591 } 592 } 593 else // Start point 594 { 595 cptr->patternloopstartpoint = mod->patternpos; 596 } 597 598 break; 599 600 case EFFECT_E_PATTERN_DELAY: 601 /* 602 [14][14]: Delay pattern 603 Where [14][14][x] means "after this division there will be a delay 604 equivalent to the time taken to play x divisions after which the 605 pattern will be resumed". The delay only relates to the 606 interpreting of new divisions, and all effects and previous notes 607 continue during delay. 608 */ 609 610 mod->patterndelay = (effect & 0xF); 611 break; 612 613 case EFFECT_E_NOTE_CUT: 614 /* 615 [14][12]: Cut sample 616 Where [14][12][x] means "after the current sample has been played 617 for x ticks in this division, its volume will be set to 0". This 618 implies that if x is 0, then you will not hear any of the sample. 619 If you wish to insert "silence" in a pattern, it is better to use a 620 "silence"-sample (see above) due to the lack of proper support for 621 this effect. 622 */ 623 cptr->effect = EFFECT_E_NOTE_CUT; 624 cptr->cut_param = (effect & 0xF); 625 if(!cptr->cut_param) 626 cptr->volume = 0; 627 break; 628 629 default: 630 631 break; 632 } 633 break; 634 635 case 0xF: 636 /* 637 [15]: Set speed 638 Where [15][x][y] means "set speed to x*16+y". Though it is nowhere 639 near that simple. Let z = x*16+y. Depending on what values z takes, 640 different units of speed are set, there being two: ticks/division 641 and beats/minute (though this one is only a label and not strictly 642 true). If z=0, then what should technically happen is that the 643 module stops, but in practice it is treated as if z=1, because 644 there is already a method for stopping the module (running out of 645 patterns). If z<=32, then it means "set ticks/division to z" 646 otherwise it means "set beats/minute to z" (convention says that 647 this should read "If z<32.." but there are some composers out there 648 that defy conventions). Default values are 6 ticks/division, and 649 125 beats/minute (4 divisions = 1 beat). The beats/minute tag is 650 only meaningful for 6 ticks/division. To get a more accurate view 651 of how things work, use the following formula: 652 24 * beats/minute 653 divisions/minute = ----------------- 654 ticks/division 655 Hence divisions/minute range from 24.75 to 6120, eg. to get a value 656 of 2000 divisions/minute use 3 ticks/division and 250 beats/minute. 657 If multiple "set speed" effects are performed in a single division, 658 the ones on higher-numbered channels take precedence over the ones 659 on lower-numbered channels. This effect has a large number of 660 different implementations, but the one described here has the 661 widest usage. 662 */ 663 664 if( (effect&0xFF) < 0x21 ) 665 { 666 if( effect&0xFF ) 667 { 668 mod->song.speed = effect&0xFF; 669 mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm))); 670 } 671 } 672 673 if( (effect&0xFF) >= 0x21 ) 674 { 675 /// HZ = 2 * BPM / 5 676 mod->bpm = effect&0xFF; 677 mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm))); 678 } 679 680 break; 681 682 default: 683 // Unsupported effect 684 break; 685 686 } 687 688 } 689 690 static void workeffect( note * nptr, hxcmod_channel * cptr ) 691 { 692 (void) nptr; 693 694 switch(cptr->effect) 695 { 696 case EFFECT_ARPEGGIO: 697 698 if( cptr->parameffect ) 699 { 700 cptr->decalperiod = cptr->period - cptr->Arpperiods[cptr->ArpIndex]; 701 702 cptr->ArpIndex++; 703 if( cptr->ArpIndex>2 ) 704 cptr->ArpIndex = 0; 705 } 706 break; 707 708 case EFFECT_PORTAMENTO_UP: 709 710 if(cptr->period) 711 { 712 cptr->period -= cptr->parameffect; 713 714 if( cptr->period < 113 || cptr->period > 20000 ) 715 cptr->period = 113; 716 } 717 718 break; 719 720 case EFFECT_PORTAMENTO_DOWN: 721 722 if(cptr->period) 723 { 724 cptr->period += cptr->parameffect; 725 726 if( cptr->period > 20000 ) 727 cptr->period = 20000; 728 } 729 730 break; 731 732 case EFFECT_VOLSLIDE_TONEPORTA: 733 case EFFECT_TONE_PORTAMENTO: 734 735 if( cptr->period && ( cptr->period != cptr->portaperiod ) && cptr->portaperiod ) 736 { 737 if( cptr->period > cptr->portaperiod ) 738 { 739 if( cptr->period - cptr->portaperiod >= cptr->portaspeed ) 740 { 741 cptr->period -= cptr->portaspeed; 742 } 743 else 744 { 745 cptr->period = cptr->portaperiod; 746 } 747 } 748 else 749 { 750 if( cptr->portaperiod - cptr->period >= cptr->portaspeed ) 751 { 752 cptr->period += cptr->portaspeed; 753 } 754 else 755 { 756 cptr->period = cptr->portaperiod; 757 } 758 } 759 760 if( cptr->period == cptr->portaperiod ) 761 { 762 // If the slide is over, don't let it to be retriggered. 763 cptr->portaperiod = 0; 764 } 765 } 766 767 if( cptr->effect == EFFECT_VOLSLIDE_TONEPORTA ) 768 { 769 if( cptr->volumeslide > 0x0F ) 770 { 771 cptr->volume = cptr->volume + (cptr->volumeslide>>4); 772 773 if(cptr->volume>63) 774 cptr->volume = 63; 775 } 776 else 777 { 778 cptr->volume = cptr->volume - (cptr->volumeslide); 779 780 if(cptr->volume>63) 781 cptr->volume=0; 782 } 783 } 784 break; 785 786 case EFFECT_VOLSLIDE_VIBRATO: 787 case EFFECT_VIBRATO: 788 789 cptr->vibraperiod = ( (cptr->vibraparam&0xF) * sintable[cptr->vibrapointeur&0x1F] )>>7; 790 791 if( cptr->vibrapointeur > 31 ) 792 cptr->vibraperiod = -cptr->vibraperiod; 793 794 cptr->vibrapointeur = (cptr->vibrapointeur+(((cptr->vibraparam>>4))&0xf)) & 0x3F; 795 796 if( cptr->effect == EFFECT_VOLSLIDE_VIBRATO ) 797 { 798 if( cptr->volumeslide > 0xF ) 799 { 800 cptr->volume = cptr->volume+(cptr->volumeslide>>4); 801 802 if( cptr->volume > 64 ) 803 cptr->volume = 64; 804 } 805 else 806 { 807 cptr->volume = cptr->volume - cptr->volumeslide; 808 809 if( cptr->volume > 64 ) 810 cptr->volume = 0; 811 } 812 } 813 814 break; 815 816 case EFFECT_VOLUME_SLIDE: 817 818 if( cptr->volumeslide > 0xF ) 819 { 820 cptr->volume += (cptr->volumeslide>>4); 821 822 if( cptr->volume > 64 ) 823 cptr->volume = 64; 824 } 825 else 826 { 827 cptr->volume -= (cptr->volumeslide&0xf); 828 829 if( cptr->volume > 64 ) 830 cptr->volume = 0; 831 } 832 break; 833 834 case EFFECT_E_NOTE_CUT: 835 if(cptr->cut_param) 836 cptr->cut_param--; 837 838 if(!cptr->cut_param) 839 cptr->volume = 0; 840 break; 841 842 default: 843 break; 844 845 } 846 847 } 848 849 /////////////////////////////////////////////////////////////////////////////////// 850 int hxcmod_init(modcontext * modctx) 851 { 852 muint i,j; 853 854 if( modctx ) 855 { 856 memclear(modctx,0,sizeof(modcontext)); 857 modctx->playrate = 44100; 858 modctx->stereo = 1; 859 modctx->stereo_separation = 1; 860 modctx->bits = 16; 861 modctx->filter = 1; 862 863 for(i=0;i<PERIOD_TABLE_LENGTH - 1;i++) 864 { 865 for(j=0;j<8;j++) 866 { 867 modctx->fullperiod[(i*8) + j] = periodtable[i] - ((( periodtable[i] - periodtable[i+1] ) / 8) * j); 868 } 869 } 870 871 return 1; 872 } 873 874 return 0; 875 } 876 877 int hxcmod_setcfg(modcontext * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter) 878 { 879 if( modctx ) 880 { 881 modctx->playrate = samplerate; 882 883 if( stereo ) 884 modctx->stereo = 1; 885 else 886 modctx->stereo = 0; 887 888 if(stereo_separation < 4) 889 { 890 modctx->stereo_separation = stereo_separation; 891 } 892 893 if( bits == 8 || bits == 16 ) 894 { 895 modctx->bits = bits; 896 } 897 898 if( filter ) 899 modctx->filter = 1; 900 else 901 modctx->filter = 0; 902 903 return 1; 904 } 905 906 return 0; 907 } 908 909 int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size ) 910 { 911 muint i, max; 912 unsigned short t; 913 sample *sptr; 914 unsigned char * modmemory,* endmodmemory; 915 916 modmemory = (unsigned char *)mod_data; 917 endmodmemory = modmemory + mod_data_size; 918 919 if(modmemory) 920 { 921 if( modctx ) 922 { 923 memcopy(&(modctx->song.title),modmemory,1084); 924 925 i = 0; 926 modctx->number_of_channels = 0; 927 while(modlist[i].numberofchannels) 928 { 929 if(memcompare(modctx->song.signature,modlist[i].signature,4)) 930 { 931 modctx->number_of_channels = modlist[i].numberofchannels; 932 } 933 934 i++; 935 } 936 937 if( !modctx->number_of_channels ) 938 { 939 // 15 Samples modules support 940 // Shift the whole datas to make it look likes a standard 4 channels mod. 941 memcopy(&(modctx->song.signature), (void*)"M.K.", 4); 942 memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130); 943 memclear(&(modctx->song.samples[15]), 0, 480); 944 modmemory += 600; 945 modctx->number_of_channels = 4; 946 } 947 else 948 { 949 modmemory += 1084; 950 } 951 952 if( modmemory >= endmodmemory ) 953 return 0; // End passed ? - Probably a bad file ! 954 955 // Patterns loading 956 for (i = max = 0; i < 128; i++) 957 { 958 while (max <= modctx->song.patterntable[i]) 959 { 960 modctx->patterndata[max] = (note*)modmemory; 961 modmemory += (256*modctx->number_of_channels); 962 max++; 963 964 if( modmemory >= endmodmemory ) 965 return 0; // End passed ? - Probably a bad file ! 966 } 967 } 968 969 for (i = 0; i < 31; i++) 970 modctx->sampledata[i]=0; 971 972 // Samples loading 973 for (i = 0, sptr = modctx->song.samples; i <31; i++, sptr++) 974 { 975 t= (sptr->length &0xFF00)>>8 | (sptr->length &0xFF)<<8; 976 sptr->length = t*2; 977 978 t= (sptr->reppnt &0xFF00)>>8 | (sptr->reppnt &0xFF)<<8; 979 sptr->reppnt = t*2; 980 981 t= (sptr->replen &0xFF00)>>8 | (sptr->replen &0xFF)<<8; 982 sptr->replen = t*2; 983 984 985 if (sptr->length == 0) continue; 986 987 modctx->sampledata[i] = (mchar*)modmemory; 988 modmemory += sptr->length; 989 990 if (sptr->replen + sptr->reppnt > sptr->length) 991 sptr->replen = sptr->length - sptr->reppnt; 992 993 if( modmemory > endmodmemory ) 994 return 0; // End passed ? - Probably a bad file ! 995 } 996 997 // States init 998 999 modctx->tablepos = 0; 1000 modctx->patternpos = 0; 1001 modctx->song.speed = 6; 1002 modctx->bpm = 125; 1003 modctx->samplenb = 0; 1004 1005 modctx->patternticks = (((long)modctx->song.speed * modctx->playrate * 5)/ (2 * modctx->bpm)) + 1; 1006 modctx->patternticksaim = ((long)modctx->song.speed * modctx->playrate * 5) / (2 * modctx->bpm); 1007 1008 modctx->sampleticksconst = 3546894UL / modctx->playrate; //8448*428/playrate; 1009 1010 for(i=0; i < modctx->number_of_channels; i++) 1011 { 1012 modctx->channels[i].volume = 0; 1013 modctx->channels[i].period = 0; 1014 } 1015 1016 modctx->mod_loaded = 1; 1017 1018 return 1; 1019 } 1020 } 1021 1022 return 0; 1023 } 1024 1025 void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, unsigned long nbsample, tracker_buffer_state * trkbuf ) 1026 { 1027 unsigned long i, j; 1028 unsigned long k; 1029 unsigned char c; 1030 unsigned int state_remaining_steps; 1031 int l,r; 1032 int ll,lr; 1033 int tl,tr; 1034 short finalperiod; 1035 note *nptr; 1036 hxcmod_channel *cptr; 1037 1038 if( modctx && outbuffer ) 1039 { 1040 if(modctx->mod_loaded) 1041 { 1042 state_remaining_steps = 0; 1043 1044 if( trkbuf ) 1045 { 1046 trkbuf->cur_rd_index = 0; 1047 1048 memcopy(trkbuf->name,modctx->song.title,sizeof(modctx->song.title)); 1049 1050 for(i=0;i<31;i++) 1051 { 1052 memcopy(trkbuf->instruments[i].name,modctx->song.samples[i].name,sizeof(trkbuf->instruments[i].name)); 1053 } 1054 } 1055 1056 ll = modctx->last_l_sample; 1057 lr = modctx->last_r_sample; 1058 1059 for (i = 0; i < nbsample; i++) 1060 { 1061 //--------------------------------------- 1062 if( modctx->patternticks++ > modctx->patternticksaim ) 1063 { 1064 if( !modctx->patterndelay ) 1065 { 1066 nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]]; 1067 nptr = nptr + modctx->patternpos; 1068 cptr = modctx->channels; 1069 1070 modctx->patternticks = 0; 1071 modctx->patterntickse = 0; 1072 1073 for(c=0;c<modctx->number_of_channels;c++) 1074 { 1075 worknote((note*)(nptr+c), (hxcmod_channel*)(cptr+c),(char)(c+1),modctx); 1076 } 1077 1078 if( !modctx->jump_loop_effect ) 1079 modctx->patternpos += modctx->number_of_channels; 1080 else 1081 modctx->jump_loop_effect = 0; 1082 1083 if( modctx->patternpos == 64*modctx->number_of_channels ) 1084 { 1085 modctx->tablepos++; 1086 modctx->patternpos = 0; 1087 if(modctx->tablepos >= modctx->song.length) 1088 modctx->tablepos = 0; 1089 } 1090 } 1091 else 1092 { 1093 modctx->patterndelay--; 1094 modctx->patternticks = 0; 1095 modctx->patterntickse = 0; 1096 } 1097 1098 } 1099 1100 if( modctx->patterntickse++ > (modctx->patternticksaim/modctx->song.speed) ) 1101 { 1102 nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]]; 1103 nptr = nptr + modctx->patternpos; 1104 cptr = modctx->channels; 1105 1106 for(c=0;c<modctx->number_of_channels;c++) 1107 { 1108 workeffect(nptr+c, cptr+c); 1109 } 1110 1111 modctx->patterntickse = 0; 1112 } 1113 1114 //--------------------------------------- 1115 1116 if( trkbuf && !state_remaining_steps ) 1117 { 1118 if( trkbuf->nb_of_state < trkbuf->nb_max_of_state ) 1119 { 1120 memclear(&trkbuf->track_state_buf[trkbuf->nb_of_state],0,sizeof(tracker_state)); 1121 } 1122 } 1123 1124 l=0; 1125 r=0; 1126 1127 for(j =0, cptr = modctx->channels; j < modctx->number_of_channels ; j++, cptr++) 1128 { 1129 if( cptr->period != 0 ) 1130 { 1131 finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod; 1132 if( finalperiod ) 1133 { 1134 cptr->samppos += ( (modctx->sampleticksconst<<10) / finalperiod ); 1135 } 1136 1137 cptr->ticks++; 1138 1139 if( cptr->replen<=2 ) 1140 { 1141 if( (cptr->samppos>>10) >= (cptr->length) ) 1142 { 1143 cptr->length = 0; 1144 cptr->reppnt = 0; 1145 1146 if( cptr->length ) 1147 cptr->samppos = cptr->samppos % (((unsigned long)cptr->length)<<10); 1148 else 1149 cptr->samppos = 0; 1150 } 1151 } 1152 else 1153 { 1154 if( (cptr->samppos>>10) >= (unsigned long)(cptr->replen+cptr->reppnt) ) 1155 { 1156 cptr->samppos = ((unsigned long)(cptr->reppnt)<<10) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<10)); 1157 } 1158 } 1159 1160 k = cptr->samppos >> 10; 1161 1162 if( cptr->sampdata!=0 && ( ((j&3)==1) || ((j&3)==2) ) ) 1163 { 1164 r += ( cptr->sampdata[k] * cptr->volume ); 1165 } 1166 1167 if( cptr->sampdata!=0 && ( ((j&3)==0) || ((j&3)==3) ) ) 1168 { 1169 l += ( cptr->sampdata[k] * cptr->volume ); 1170 } 1171 1172 if( trkbuf && !state_remaining_steps ) 1173 { 1174 if( trkbuf->nb_of_state < trkbuf->nb_max_of_state ) 1175 { 1176 trkbuf->track_state_buf[trkbuf->nb_of_state].number_of_tracks = modctx->number_of_channels; 1177 trkbuf->track_state_buf[trkbuf->nb_of_state].buf_index = i; 1178 trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern = modctx->song.patterntable[modctx->tablepos]; 1179 trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_pos = modctx->patternpos / modctx->number_of_channels; 1180 trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_table_pos = modctx->tablepos; 1181 trkbuf->track_state_buf[trkbuf->nb_of_state].bpm = modctx->bpm; 1182 trkbuf->track_state_buf[trkbuf->nb_of_state].speed = modctx->song.speed; 1183 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_effect = cptr->effect_code; 1184 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_parameffect = cptr->parameffect; 1185 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = finalperiod; 1186 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_volume = cptr->volume; 1187 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].instrument_number = (unsigned char)cptr->sampnum; 1188 } 1189 } 1190 } 1191 } 1192 1193 if( trkbuf && !state_remaining_steps ) 1194 { 1195 state_remaining_steps = trkbuf->sample_step; 1196 1197 if(trkbuf->nb_of_state < trkbuf->nb_max_of_state) 1198 trkbuf->nb_of_state++; 1199 } 1200 else 1201 { 1202 state_remaining_steps--; 1203 } 1204 1205 tl = (short)l; 1206 tr = (short)r; 1207 1208 if ( modctx->filter ) 1209 { 1210 // Filter 1211 l = (l+ll)>>1; 1212 r = (r+lr)>>1; 1213 } 1214 1215 if ( modctx->stereo_separation == 1 ) 1216 { 1217 // Left & Right Stereo panning 1218 l = (l+(r>>1)); 1219 r = (r+(l>>1)); 1220 } 1221 1222 // Level limitation 1223 if( l > 32767 ) l = 32767; 1224 if( l < -32768 ) l = -32768; 1225 if( r > 32767 ) r = 32767; 1226 if( r < -32768 ) r = -32768; 1227 1228 // Store the final sample. 1229 outbuffer[(i*2)] = l; 1230 outbuffer[(i*2)+1] = r; 1231 1232 ll = tl; 1233 lr = tr; 1234 1235 } 1236 1237 modctx->last_l_sample = ll; 1238 modctx->last_r_sample = lr; 1239 1240 modctx->samplenb = modctx->samplenb+nbsample; 1241 } 1242 else 1243 { 1244 for (i = 0; i < nbsample; i++) 1245 { 1246 // Mod not loaded. Return blank buffer. 1247 outbuffer[(i*2)] = 0; 1248 outbuffer[(i*2)+1] = 0; 1249 } 1250 1251 if(trkbuf) 1252 { 1253 trkbuf->nb_of_state = 0; 1254 trkbuf->cur_rd_index = 0; 1255 trkbuf->name[0] = 0; 1256 memclear(trkbuf->track_state_buf,0,sizeof(tracker_state) * trkbuf->nb_max_of_state); 1257 memclear(trkbuf->instruments,0,sizeof(trkbuf->instruments)); 1258 } 1259 } 1260 } 1261 } 1262 1263 void hxcmod_unload( modcontext * modctx ) 1264 { 1265 if(modctx) 1266 { 1267 memclear(&modctx->song,0,sizeof(modctx->song)); 1268 memclear(&modctx->sampledata,0,sizeof(modctx->sampledata)); 1269 memclear(&modctx->patterndata,0,sizeof(modctx->patterndata)); 1270 modctx->tablepos = 0; 1271 modctx->patternpos = 0; 1272 modctx->patterndelay = 0; 1273 modctx->jump_loop_effect = 0; 1274 modctx->bpm = 0; 1275 modctx->patternticks = 0; 1276 modctx->patterntickse = 0; 1277 modctx->patternticksaim = 0; 1278 modctx->sampleticksconst = 0; 1279 1280 modctx->samplenb = 0; 1281 1282 memclear(modctx->channels,0,sizeof(modctx->channels)); 1283 1284 modctx->number_of_channels = 0; 1285 1286 modctx->mod_loaded = 0; 1287 1288 modctx->last_r_sample = 0; 1289 modctx->last_l_sample = 0; 1290 } 1291 } 1292