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