1 /* OpenCP Module Player 2 * copyright (c) 2019 Stian Skjelstad <stian.skjelstad@gmail.com> 3 * 4 * Renderer routine. Heavily based on https://github.com/pete-gordon/hivelytracker/tree/master/hvl2wav 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 #include "config.h" 22 #include <math.h> 23 #include <string.h> 24 #include "types.h" 25 #include "player.h" 26 27 int32_t __attribute__ ((visibility ("internal"))) stereopan_left[5] = { 128, 96, 64, 32, 0 }; 28 int32_t __attribute__ ((visibility ("internal"))) stereopan_right[5] = { 128, 160, 193, 225, 255 }; 29 30 /* 31 ** Waves 32 */ 33 int8_t __attribute__ ((visibility ("internal"))) waves[WAVES_SIZE]; 34 //static int16 waves2[WAVES_SIZE]; 35 36 static const int16_t vib_tab[] = 37 { 38 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, 39 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24, 40 0, -24, -49, -74, -97, -120, -141, -161, -180, -197, -212, -224, -235, -244, -250, -253, 41 -255, -253, -250, -244, -235, -224, -212, -197, -180, -161, -141, -120, -97, -74, -49, -24 42 }; 43 44 static const uint16_t period_tab[] = 45 { 46 0x0000, 0x0D60, 0x0CA0, 0x0BE8, 0x0B40, 0x0A98, 0x0A00, 0x0970, 47 0x08E8, 0x0868, 0x07F0, 0x0780, 0x0714, 0x06B0, 0x0650, 0x05F4, 48 0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0, 49 0x038A, 0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C, 50 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5, 0x01AC, 0x0194, 0x017D, 51 0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0, 52 0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0, 0x0097, 53 0x008F, 0x0087, 0x007F, 0x0078, 0x0071 54 }; 55 56 static uint32_t panning_left[256], panning_right[256]; 57 58 static void hvl_GenPanningTables (void) 59 { 60 uint32_t i; 61 double aa, ab; 62 63 // Sine based panning table 64 aa = M_PI_2; // Quarter of the way through the sinewave == top peak 65 ab = 0.0f; // Start of the climb from zero 66 67 for( i=0; i<256; i++ ) 68 { 69 panning_left[i] = (uint32_t)(sin(aa)*255.0f); 70 panning_right[i] = (uint32_t)(sin(ab)*255.0f); 71 72 aa += (M_PI_2)/256.0f; 73 ab += (M_PI_2)/256.0f; 74 } 75 panning_left[255] = 0; 76 panning_right[0] = 0; 77 } 78 79 #include "hvl_genwaves.inc.c" 80 81 static void hvl_reset_some_stuff( struct hvl_tune *ht ) 82 { 83 uint32_t i; 84 85 for ( i=0; i<MAX_CHANNELS; i++ ) 86 { 87 ht->ht_Voices[i].vc_Instrument = 0; 88 89 ht->ht_Voices[i].vc_SamplePos = 0; 90 ht->ht_Voices[i].vc_Track = 0; 91 ht->ht_Voices[i].vc_Transpose = 0; 92 ht->ht_Voices[i].vc_NextTrack = 0; 93 ht->ht_Voices[i].vc_NextTranspose = 0; 94 ht->ht_Voices[i].vc_ADSRVolume = 0; 95 ht->ht_Voices[i].vc_InstrPeriod = 0; 96 ht->ht_Voices[i].vc_TrackPeriod = 0; 97 ht->ht_Voices[i].vc_VibratoPeriod = 0; 98 ht->ht_Voices[i].vc_NoteMaxVolume = 0; 99 ht->ht_Voices[i].vc_PerfSubVolume = 0; 100 ht->ht_Voices[i].vc_TrackMasterVolume = 0; 101 ht->ht_Voices[i].vc_NewWaveform = 0; 102 ht->ht_Voices[i].vc_Waveform = 0; 103 ht->ht_Voices[i].vc_PlantSquare = 0; 104 ht->ht_Voices[i].vc_PlantPeriod = 0; 105 ht->ht_Voices[i].vc_IgnoreSquare = 0; 106 ht->ht_Voices[i].vc_TrackOn = 0; 107 ht->ht_Voices[i].vc_FixedNote = 0; 108 ht->ht_Voices[i].vc_VolumeSlideUp = 0; 109 ht->ht_Voices[i].vc_VolumeSlideDown = 0; 110 ht->ht_Voices[i].vc_HardCut = 0; 111 ht->ht_Voices[i].vc_HardCutRelease = 0; 112 ht->ht_Voices[i].vc_HardCutReleaseF = 0; 113 ht->ht_Voices[i].vc_PeriodSlideSpeed = 0; 114 ht->ht_Voices[i].vc_PeriodSlidePeriod = 0; 115 ht->ht_Voices[i].vc_PeriodSlideLimit = 0; 116 ht->ht_Voices[i].vc_PeriodSlideOn = 0; 117 ht->ht_Voices[i].vc_PeriodSlideWithLimit = 0; 118 ht->ht_Voices[i].vc_PeriodPerfSlideSpeed = 0; 119 ht->ht_Voices[i].vc_PeriodPerfSlidePeriod = 0; 120 ht->ht_Voices[i].vc_PeriodPerfSlideOn = 0; 121 ht->ht_Voices[i].vc_VibratoDelay = 0; 122 ht->ht_Voices[i].vc_VibratoCurrent = 0; 123 ht->ht_Voices[i].vc_VibratoDepth = 0; 124 ht->ht_Voices[i].vc_VibratoSpeed = 0; 125 ht->ht_Voices[i].vc_SquareOn = 0; 126 ht->ht_Voices[i].vc_SquareInit = 0; 127 ht->ht_Voices[i].vc_SquareLowerLimit = 0; 128 ht->ht_Voices[i].vc_SquareUpperLimit = 0; 129 ht->ht_Voices[i].vc_SquarePos = 0; 130 ht->ht_Voices[i].vc_SquareSign = 0; 131 ht->ht_Voices[i].vc_SquareSlidingIn = 0; 132 ht->ht_Voices[i].vc_SquareReverse = 0; 133 ht->ht_Voices[i].vc_FilterOn = 0; 134 ht->ht_Voices[i].vc_FilterInit = 0; 135 ht->ht_Voices[i].vc_FilterLowerLimit = 0; 136 ht->ht_Voices[i].vc_FilterUpperLimit = 0; 137 ht->ht_Voices[i].vc_FilterPos = 0; 138 ht->ht_Voices[i].vc_FilterSign = 0; 139 ht->ht_Voices[i].vc_FilterSpeed = 0; 140 ht->ht_Voices[i].vc_FilterSlidingIn = 0; 141 ht->ht_Voices[i].vc_IgnoreFilter = 0; 142 ht->ht_Voices[i].vc_PerfCurrent = 0; 143 ht->ht_Voices[i].vc_PerfSpeed = 0; 144 ht->ht_Voices[i].vc_WaveLength = 0; 145 ht->ht_Voices[i].vc_NoteDelayOn = 0; 146 ht->ht_Voices[i].vc_NoteCutOn = 0; 147 ht->ht_Voices[i].vc_AudioPeriod = 0; 148 ht->ht_Voices[i].vc_AudioVolume = 0; 149 ht->ht_Voices[i].vc_VoiceVolume = 0; 150 ht->ht_Voices[i].vc_VoicePeriod = 0; 151 ht->ht_Voices[i].vc_VoiceNum = 0; 152 ht->ht_Voices[i].vc_WNRandom = 0; 153 ht->ht_Voices[i].vc_SquareWait = 0; 154 ht->ht_Voices[i].vc_FilterWait = 0; 155 ht->ht_Voices[i].vc_PerfWait = 0; 156 ht->ht_Voices[i].vc_NoteDelayWait = 0; 157 ht->ht_Voices[i].vc_NoteCutWait = 0; 158 ht->ht_Voices[i].vc_PerfList = 0; 159 ht->ht_Voices[i].vc_RingSamplePos = 0; 160 ht->ht_Voices[i].vc_RingDelta = 0; 161 ht->ht_Voices[i].vc_RingPlantPeriod = 0; 162 ht->ht_Voices[i].vc_RingAudioPeriod = 0; 163 ht->ht_Voices[i].vc_RingNewWaveform = 0; 164 ht->ht_Voices[i].vc_RingWaveform = 0; 165 ht->ht_Voices[i].vc_RingFixedPeriod = 0; 166 ht->ht_Voices[i].vc_RingBasePeriod = 0; 167 168 ht->ht_Voices[i].vc_RingMixSource = NULL; 169 ht->ht_Voices[i].vc_RingAudioSource = NULL; 170 171 memset(&ht->ht_Voices[i].vc_SquareTempBuffer, 0, 0x80); 172 memset(&ht->ht_Voices[i].vc_ADSR, 0, sizeof (struct hvl_envelope)); 173 memset(&ht->ht_Voices[i].vc_VoiceBuffer, 0 ,0x281); 174 memset(&ht->ht_Voices[i].vc_RingVoiceBuffer, 0 ,0x281); 175 176 ht->ht_Voices[i].vc_Delta = 1; 177 ht->ht_Voices[i].vc_OverrideTranspose = 1000; // 1.5 178 ht->ht_Voices[i].vc_WNRandom = 0x280; 179 ht->ht_Voices[i].vc_VoiceNum = i; 180 ht->ht_Voices[i].vc_TrackMasterVolume = 0x40; 181 ht->ht_Voices[i].vc_TrackOn = 1; 182 ht->ht_Voices[i].vc_MixSource = ht->ht_Voices[i].vc_VoiceBuffer; 183 } 184 185 ht->ht_defpanleft = stereopan_left[ht->ht_defstereo]; 186 ht->ht_defpanright = stereopan_right[ht->ht_defstereo]; 187 } 188 189 /* half-public */ 190 void __attribute__ ((visibility ("internal"))) hvl_InitReplayer( void ) 191 { 192 hvl_GenPanningTables (); 193 hvl_GenSawtooth ( &waves[WO_SAWTOOTH_04], 0x04 ); 194 hvl_GenSawtooth ( &waves[WO_SAWTOOTH_08], 0x08 ); 195 hvl_GenSawtooth ( &waves[WO_SAWTOOTH_10], 0x10 ); 196 hvl_GenSawtooth ( &waves[WO_SAWTOOTH_20], 0x20 ); 197 hvl_GenSawtooth ( &waves[WO_SAWTOOTH_40], 0x40 ); 198 hvl_GenSawtooth ( &waves[WO_SAWTOOTH_80], 0x80 ); 199 hvl_GenTriangle ( &waves[WO_TRIANGLE_04], 0x04 ); 200 hvl_GenTriangle ( &waves[WO_TRIANGLE_08], 0x08 ); 201 hvl_GenTriangle ( &waves[WO_TRIANGLE_10], 0x10 ); 202 hvl_GenTriangle ( &waves[WO_TRIANGLE_20], 0x20 ); 203 hvl_GenTriangle ( &waves[WO_TRIANGLE_40], 0x40 ); 204 hvl_GenTriangle ( &waves[WO_TRIANGLE_80], 0x80 ); initialize_windowaggregate(WindowAggState * winstate,WindowStatePerFunc perfuncstate,WindowStatePerAgg peraggstate)205 hvl_GenSquare ( &waves[WO_SQUARES] ); 206 hvl_GenWhiteNoise ( &waves[WO_WHITENOISE], WHITENOISELEN ); 207 hvl_GenFilterWaves ( &waves[WO_TRIANGLE_04], &waves[WO_LOWPASSES], &waves[WO_HIGHPASSES] ); 208 } 209 210 /* half-public */ 211 int __attribute__ ((visibility ("internal"))) hvl_InitSubsong ( struct hvl_tune *ht, uint32_t nr ) 212 { 213 uint32_t PosNr, i; 214 215 if ( nr > ht->ht_SubsongNr ) 216 { 217 return FALSE; 218 } 219 220 ht->ht_SongNum = nr; 221 222 PosNr = 0; 223 if ( nr ) 224 { 225 PosNr = ht->ht_Subsongs[nr-1]; 226 } 227 228 ht->ht_PosNr = PosNr; 229 ht->ht_PosJump = 0; 230 ht->ht_PatternBreak = 0; 231 ht->ht_NoteNr = 0; 232 ht->ht_PosJumpNote = 0; 233 ht->ht_Tempo = 6; 234 ht->ht_StepWaitFrames = 0; 235 ht->ht_GetNewPosition = 1; 236 ht->ht_SongEndReached = 0; 237 ht->ht_PlayingTime = 0; 238 239 for ( i=0; i<MAX_CHANNELS; i+=4 ) advance_windowaggregate(WindowAggState * winstate,WindowStatePerFunc perfuncstate,WindowStatePerAgg peraggstate)240 { 241 ht->ht_Voices[i+0].vc_Pan = ht->ht_defpanleft; 242 ht->ht_Voices[i+0].vc_SetPan = ht->ht_defpanleft; // 1.4 243 ht->ht_Voices[i+0].vc_PanMultLeft = panning_left[ht->ht_defpanleft]; 244 ht->ht_Voices[i+0].vc_PanMultRight = panning_right[ht->ht_defpanleft]; 245 ht->ht_Voices[i+1].vc_Pan = ht->ht_defpanright; 246 ht->ht_Voices[i+1].vc_SetPan = ht->ht_defpanright; // 1.4 247 ht->ht_Voices[i+1].vc_PanMultLeft = panning_left[ht->ht_defpanright]; 248 ht->ht_Voices[i+1].vc_PanMultRight = panning_right[ht->ht_defpanright]; 249 ht->ht_Voices[i+2].vc_Pan = ht->ht_defpanright; 250 ht->ht_Voices[i+2].vc_SetPan = ht->ht_defpanright; // 1.4 251 ht->ht_Voices[i+2].vc_PanMultLeft = panning_left[ht->ht_defpanright]; 252 ht->ht_Voices[i+2].vc_PanMultRight = panning_right[ht->ht_defpanright]; 253 ht->ht_Voices[i+3].vc_Pan = ht->ht_defpanleft; 254 ht->ht_Voices[i+3].vc_SetPan = ht->ht_defpanleft; // 1.4 255 ht->ht_Voices[i+3].vc_PanMultLeft = panning_left[ht->ht_defpanleft]; 256 ht->ht_Voices[i+3].vc_PanMultRight = panning_right[ht->ht_defpanleft]; 257 } 258 259 hvl_reset_some_stuff ( ht ); 260 261 return TRUE; 262 } 263 264 static void hvl_process_stepfx_1 ( struct hvl_tune *ht, struct hvl_voice *voice, int32_t FX, int32_t FXParam ) 265 { 266 switch ( FX ) 267 { 268 case 0x0: // Position Jump HI 269 if ( ((FXParam&0x0f) > 0) && ((FXParam&0x0f) <= 9) ) 270 { 271 ht->ht_PosJump = FXParam & 0xf; 272 } 273 break; 274 275 case 0x5: // Volume Slide + Tone Portamento 276 case 0xa: // Volume Slide 277 voice->vc_VolumeSlideDown = FXParam & 0x0f; 278 voice->vc_VolumeSlideUp = FXParam >> 4; 279 break; 280 281 case 0x7: // Panning 282 if ( FXParam > 127 ) 283 { 284 FXParam -= 256; 285 } 286 voice->vc_Pan = (FXParam+128); 287 voice->vc_SetPan = (FXParam+128); // 1.4 288 voice->vc_PanMultLeft = panning_left[voice->vc_Pan]; 289 voice->vc_PanMultRight = panning_right[voice->vc_Pan]; 290 break; 291 292 case 0xb: // Position jump 293 ht->ht_PosJump = ht->ht_PosJump*100 + (FXParam & 0x0f) + (FXParam >> 4)*10; 294 ht->ht_PatternBreak = 1; 295 if ( ht->ht_PosJump <= ht->ht_PosNr ) 296 { 297 ht->ht_SongEndReached = 1; 298 } 299 break; 300 301 case 0xd: // Pattern break 302 ht->ht_PosJump = ht->ht_PosNr+1; 303 ht->ht_PosJumpNote = (FXParam & 0x0f) + (FXParam>>4)*10; 304 ht->ht_PatternBreak = 1; 305 if ( ht->ht_PosJumpNote > ht->ht_TrackLength ) 306 { 307 ht->ht_PosJumpNote = 0; 308 } 309 break; 310 311 case 0xe: // Extended commands 312 switch ( FXParam >> 4 ) 313 { 314 case 0xc: // Note cut 315 if ( (FXParam & 0x0f) < ht->ht_Tempo ) 316 { 317 voice->vc_NoteCutWait = FXParam & 0x0f; 318 if ( voice->vc_NoteCutWait ) 319 { 320 voice->vc_NoteCutOn = 1; 321 voice->vc_HardCutRelease = 0; 322 } 323 } 324 break; 325 326 // 1.6: 0xd case removed 327 } 328 break; 329 330 case 0xf: // Speed 331 ht->ht_Tempo = FXParam; 332 if ( FXParam == 0 ) 333 { 334 ht->ht_SongEndReached = 1; 335 } 336 break; 337 } 338 } 339 340 static void hvl_process_stepfx_2 ( struct hvl_tune *ht, struct hvl_voice *voice, int32_t FX, int32_t FXParam, int32_t *Note ) 341 { 342 switch ( FX ) 343 { 344 case 0x9: // Set squarewave offset 345 voice->vc_SquarePos = FXParam >> (5 - voice->vc_WaveLength); 346 voice->vc_PlantSquare = 1; 347 voice->vc_IgnoreSquare = 1; 348 break; 349 350 case 0x3: // Tone portamento 351 if ( FXParam != 0 ) 352 { 353 voice->vc_PeriodSlideSpeed = FXParam; 354 } 355 case 0x5: // Tone portamento + volume slide 356 if ( *Note ) 357 { 358 int32_t new, diff; 359 360 new = period_tab[*Note]; 361 diff = period_tab[voice->vc_TrackPeriod]; 362 diff -= new; 363 new = diff + voice->vc_PeriodSlidePeriod; 364 365 if( new ) 366 { 367 voice->vc_PeriodSlideLimit = -diff; 368 } 369 } 370 voice->vc_PeriodSlideOn = 1; 371 voice->vc_PeriodSlideWithLimit = 1; 372 *Note = 0; 373 break; 374 } 375 } 376 377 static void hvl_process_stepfx_3 ( struct hvl_tune *ht, struct hvl_voice *voice, int32_t FX, int32_t FXParam ) 378 { 379 int32_t i; 380 381 switch ( FX ) 382 { 383 case 0x01: // Portamento up (period slide down) 384 voice->vc_PeriodSlideSpeed = -FXParam; 385 voice->vc_PeriodSlideOn = 1; 386 voice->vc_PeriodSlideWithLimit = 0; 387 break; 388 case 0x02: // Portamento down 389 voice->vc_PeriodSlideSpeed = FXParam; 390 voice->vc_PeriodSlideOn = 1; 391 voice->vc_PeriodSlideWithLimit = 0; 392 break; 393 case 0x04: // Filter override 394 if ( ( FXParam == 0 ) || ( FXParam == 0x40 ) ) 395 { 396 break; 397 } 398 if ( FXParam < 0x40 ) 399 { 400 voice->vc_IgnoreFilter = FXParam; 401 break; 402 } 403 if ( FXParam > 0x7f ) 404 { 405 break; 406 } 407 voice->vc_FilterPos = FXParam - 0x40; 408 break; 409 case 0x0c: // Volume 410 FXParam &= 0xff; 411 if ( FXParam <= 0x40 ) 412 { 413 voice->vc_NoteMaxVolume = FXParam; 414 break; 415 } 416 advance_windowaggregate_base(WindowAggState * winstate,WindowStatePerFunc perfuncstate,WindowStatePerAgg peraggstate)417 if ( (FXParam -= 0x50) < 0 ) 418 { 419 break; // 1.6 420 } 421 422 if ( FXParam <= 0x40 ) 423 { 424 for( i=0; i<ht->ht_Channels; i++ ) 425 { 426 ht->ht_Voices[i].vc_TrackMasterVolume = FXParam; 427 } 428 break; 429 } 430 431 if ( (FXParam -= 0xa0-0x50) < 0 ) 432 { 433 break; // 1.6 434 } 435 436 if ( FXParam <= 0x40 ) 437 { 438 voice->vc_TrackMasterVolume = FXParam; 439 } 440 break; 441 442 case 0xe: // Extended commands; 443 switch ( FXParam >> 4 ) 444 { 445 case 0x1: // Fineslide up 446 voice->vc_PeriodSlidePeriod -= (FXParam & 0x0f); // 1.8 447 voice->vc_PlantPeriod = 1; 448 break; 449 450 case 0x2: // Fineslide down 451 voice->vc_PeriodSlidePeriod += (FXParam & 0x0f); // 1.8 452 voice->vc_PlantPeriod = 1; 453 break; 454 455 case 0x4: // Vibrato control 456 voice->vc_VibratoDepth = FXParam & 0x0f; 457 break; 458 459 case 0x0a: // Fine volume up 460 voice->vc_NoteMaxVolume += FXParam & 0x0f; 461 462 if ( voice->vc_NoteMaxVolume > 0x40 ) 463 { 464 voice->vc_NoteMaxVolume = 0x40; 465 } 466 break; 467 468 case 0x0b: // Fine volume down 469 voice->vc_NoteMaxVolume -= FXParam & 0x0f; 470 471 if ( voice->vc_NoteMaxVolume < 0 ) 472 { 473 voice->vc_NoteMaxVolume = 0; 474 } 475 break; 476 477 case 0x0f: // Misc flags (1.5) 478 if( ht->ht_Version < 1 ) 479 { 480 break; 481 } 482 switch ( FXParam & 0xf ) 483 { 484 case 1: 485 voice->vc_OverrideTranspose = voice->vc_Transpose; 486 break; 487 } 488 break; 489 } 490 break; 491 } 492 } 493 494 static void hvl_process_step ( struct hvl_tune *ht, struct hvl_voice *voice ) 495 { 496 int32_t Note, Instr, donenotedel; 497 struct hvl_step *Step; 498 499 if ( voice->vc_TrackOn == 0 ) 500 { 501 return; 502 } 503 504 voice->vc_VolumeSlideUp = 0; 505 voice->vc_VolumeSlideDown = 0; 506 507 Step = &ht->ht_Tracks 508 [ 509 ht->ht_Positions 510 [ 511 ht->ht_PosNr 512 ].pos_Track 513 [ 514 voice->vc_VoiceNum 515 ] 516 ][ 517 ht->ht_NoteNr 518 ]; 519 520 Note = Step->stp_Note; 521 Instr = Step->stp_Instrument; 522 523 // --------- 1.6: from here -------------- 524 525 donenotedel = 0; 526 527 // Do notedelay here 528 if ( ((Step->stp_FX&0xf)==0xe) && ((Step->stp_FXParam&0xf0)==0xd0) ) 529 { 530 if ( voice->vc_NoteDelayOn ) 531 { 532 voice->vc_NoteDelayOn = 0; 533 donenotedel = 1; 534 } else { 535 if ( (Step->stp_FXParam&0x0f) < ht->ht_Tempo ) 536 { 537 voice->vc_NoteDelayWait = Step->stp_FXParam & 0x0f; 538 if( voice->vc_NoteDelayWait ) 539 { 540 voice->vc_NoteDelayOn = 1; 541 return; 542 } 543 } 544 } 545 } 546 547 if ( (donenotedel==0) && ((Step->stp_FXb&0xf)==0xe) && ((Step->stp_FXbParam&0xf0)==0xd0) ) 548 { 549 if ( voice->vc_NoteDelayOn ) 550 { 551 voice->vc_NoteDelayOn = 0; 552 } else { 553 if ( (Step->stp_FXbParam&0x0f) < ht->ht_Tempo ) 554 { 555 voice->vc_NoteDelayWait = Step->stp_FXbParam & 0x0f; 556 if ( voice->vc_NoteDelayWait ) 557 { 558 voice->vc_NoteDelayOn = 1; 559 return; 560 } 561 } 562 } 563 } 564 565 // --------- 1.6: to here -------------- 566 567 if ( Note ) 568 { 569 voice->vc_OverrideTranspose = 1000; // 1.5 570 } 571 572 hvl_process_stepfx_1( ht, voice, Step->stp_FX &0xf, Step->stp_FXParam ); 573 hvl_process_stepfx_1( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam ); 574 575 if ( ( Instr ) && ( Instr <= ht->ht_InstrumentNr ) ) 576 { 577 struct hvl_instrument *Ins; 578 int16_t SquareLower, SquareUpper, d6, d3, d4; 579 finalize_windowaggregate(WindowAggState * winstate,WindowStatePerFunc perfuncstate,WindowStatePerAgg peraggstate,Datum * result,bool * isnull)580 /* 1.4: Reset panning to last set position */ 581 voice->vc_Pan = voice->vc_SetPan; 582 voice->vc_PanMultLeft = panning_left[voice->vc_Pan]; 583 voice->vc_PanMultRight = panning_right[voice->vc_Pan]; 584 585 voice->vc_PeriodSlideSpeed = 0; 586 voice->vc_PeriodSlidePeriod = 0; 587 voice->vc_PeriodSlideLimit = 0; 588 589 voice->vc_PerfSubVolume = 0x40; 590 voice->vc_ADSRVolume = 0; 591 voice->vc_Instrument = Ins = &ht->ht_Instruments[Instr]; 592 voice->vc_SamplePos = 0; 593 594 voice->vc_ADSR.aFrames = Ins->ins_Envelope.aFrames; 595 voice->vc_ADSR.aVolume = Ins->ins_Envelope.aFrames ? Ins->ins_Envelope.aVolume * 256 / voice->vc_ADSR.aFrames : Ins->ins_Envelope.aVolume * 256; 596 voice->vc_ADSR.dFrames = Ins->ins_Envelope.dFrames; 597 voice->vc_ADSR.dVolume = Ins->ins_Envelope.dFrames ? (Ins->ins_Envelope.dVolume-Ins->ins_Envelope.aVolume) * 256 / voice->vc_ADSR.dFrames : Ins->ins_Envelope.dVolume * 256; // XXX 598 voice->vc_ADSR.sFrames = Ins->ins_Envelope.sFrames; 599 voice->vc_ADSR.rFrames = Ins->ins_Envelope.rFrames; 600 voice->vc_ADSR.rVolume = Ins->ins_Envelope.rFrames ? (Ins->ins_Envelope.rVolume-Ins->ins_Envelope.dVolume) * 256 / voice->vc_ADSR.rFrames : Ins->ins_Envelope.rVolume * 256; // XXX 601 602 voice->vc_WaveLength = Ins->ins_WaveLength; 603 voice->vc_NoteMaxVolume = Ins->ins_Volume; 604 605 voice->vc_VibratoCurrent = 0; 606 voice->vc_VibratoDelay = Ins->ins_VibratoDelay; 607 voice->vc_VibratoDepth = Ins->ins_VibratoDepth; 608 voice->vc_VibratoSpeed = Ins->ins_VibratoSpeed; 609 voice->vc_VibratoPeriod = 0; 610 611 voice->vc_HardCutRelease = Ins->ins_HardCutRelease; 612 voice->vc_HardCut = Ins->ins_HardCutReleaseFrames; 613 614 voice->vc_IgnoreSquare = 0; 615 voice->vc_SquareSlidingIn = 0; 616 voice->vc_SquareWait = 0; 617 voice->vc_SquareOn = 0; 618 619 SquareLower = Ins->ins_SquareLowerLimit >> (5 - voice->vc_WaveLength); 620 SquareUpper = Ins->ins_SquareUpperLimit >> (5 - voice->vc_WaveLength); 621 622 if ( SquareUpper < SquareLower ) 623 { 624 int16_t t = SquareUpper; 625 SquareUpper = SquareLower; 626 SquareLower = t; 627 } 628 629 voice->vc_SquareUpperLimit = SquareUpper; 630 voice->vc_SquareLowerLimit = SquareLower; 631 632 voice->vc_IgnoreFilter = 0; 633 voice->vc_FilterWait = 0; 634 voice->vc_FilterOn = 0; 635 voice->vc_FilterSlidingIn = 0; 636 637 d6 = Ins->ins_FilterSpeed; 638 d3 = Ins->ins_FilterLowerLimit; 639 d4 = Ins->ins_FilterUpperLimit; 640 641 if ( d3 & 0x80 ) 642 { 643 d6 |= 0x20; 644 } 645 if ( d4 & 0x80 ) 646 { 647 d6 |= 0x40; 648 } 649 650 voice->vc_FilterSpeed = d6; 651 d3 &= ~0x80; 652 d4 &= ~0x80; 653 654 if ( d3 > d4 ) 655 { 656 int16_t t = d3; 657 d3 = d4; 658 d4 = t; 659 } 660 661 voice->vc_FilterUpperLimit = d4; eval_windowaggregates(WindowAggState * winstate)662 voice->vc_FilterLowerLimit = d3; 663 voice->vc_FilterPos = 32; 664 665 voice->vc_PerfWait = voice->vc_PerfCurrent = 0; 666 voice->vc_PerfSpeed = Ins->ins_PList.pls_Speed; 667 voice->vc_PerfList = &voice->vc_Instrument->ins_PList; 668 669 voice->vc_RingMixSource = NULL; // No ring modulation 670 voice->vc_RingSamplePos = 0; 671 voice->vc_RingPlantPeriod = 0; 672 voice->vc_RingNewWaveform = 0; 673 } 674 675 voice->vc_PeriodSlideOn = 0; 676 677 hvl_process_stepfx_2 ( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam, &Note ); 678 hvl_process_stepfx_2 ( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam, &Note ); 679 680 if ( Note ) 681 { 682 voice->vc_TrackPeriod = Note; 683 voice->vc_PlantPeriod = 1; 684 } 685 686 hvl_process_stepfx_3 ( ht, voice, Step->stp_FX&0xf, Step->stp_FXParam ); 687 hvl_process_stepfx_3 ( ht, voice, Step->stp_FXb&0xf, Step->stp_FXbParam ); 688 } 689 690 static void hvl_plist_command_parse ( struct hvl_tune *ht, struct hvl_voice *voice, int32_t FX, int32_t FXParam ) 691 { 692 switch ( FX ) 693 { 694 case 0: 695 if ( ( FXParam > 0 ) && ( FXParam < 0x40 ) ) 696 { 697 if ( voice->vc_IgnoreFilter ) 698 { 699 voice->vc_FilterPos = voice->vc_IgnoreFilter; 700 voice->vc_IgnoreFilter = 0; 701 } else { 702 voice->vc_FilterPos = FXParam; 703 } 704 voice->vc_NewWaveform = 1; 705 } 706 break; 707 708 case 1: 709 voice->vc_PeriodPerfSlideSpeed = FXParam; 710 voice->vc_PeriodPerfSlideOn = 1; 711 break; 712 713 case 2: 714 voice->vc_PeriodPerfSlideSpeed = -FXParam; 715 voice->vc_PeriodPerfSlideOn = 1; 716 break; 717 718 case 3: 719 if ( voice->vc_IgnoreSquare == 0 ) 720 { 721 voice->vc_SquarePos = FXParam >> (5-voice->vc_WaveLength); 722 } else { 723 voice->vc_IgnoreSquare = 0; 724 } 725 break; 726 727 case 4: 728 if ( FXParam == 0 ) 729 { 730 voice->vc_SquareInit = (voice->vc_SquareOn ^= 1); 731 voice->vc_SquareSign = 1; 732 } else { 733 if ( FXParam & 0x0f ) 734 { 735 voice->vc_SquareInit = (voice->vc_SquareOn ^= 1); 736 voice->vc_SquareSign = 1; 737 if (( FXParam & 0x0f ) == 0x0f ) 738 { 739 voice->vc_SquareSign = -1; 740 } 741 } 742 if ( FXParam & 0xf0 ) 743 { 744 voice->vc_FilterInit = (voice->vc_FilterOn ^= 1); 745 voice->vc_FilterSign = 1; 746 if (( FXParam & 0xf0 ) == 0xf0 ) 747 { 748 voice->vc_FilterSign = -1; 749 } 750 } 751 } 752 break; 753 754 case 5: 755 voice->vc_PerfCurrent = FXParam; 756 break; 757 758 case 7: 759 // Ring modulate with triangle 760 if (( FXParam >= 1 ) && ( FXParam <= 0x3C )) 761 { 762 voice->vc_RingBasePeriod = FXParam; 763 voice->vc_RingFixedPeriod = 1; 764 } else if (( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) 765 { 766 voice->vc_RingBasePeriod = FXParam-0x80; 767 voice->vc_RingFixedPeriod = 0; 768 } else { 769 voice->vc_RingBasePeriod = 0; 770 voice->vc_RingFixedPeriod = 0; 771 voice->vc_RingNewWaveform = 0; 772 voice->vc_RingAudioSource = NULL; // turn it off 773 voice->vc_RingMixSource = NULL; 774 break; 775 } 776 voice->vc_RingWaveform = 0; 777 voice->vc_RingNewWaveform = 1; 778 voice->vc_RingPlantPeriod = 1; 779 break; 780 781 case 8: // Ring modulate with sawtooth 782 if (( FXParam >= 1 ) && ( FXParam <= 0x3C )) 783 { 784 voice->vc_RingBasePeriod = FXParam; 785 voice->vc_RingFixedPeriod = 1; 786 } else if (( FXParam >= 0x81 ) && ( FXParam <= 0xBC )) 787 { 788 voice->vc_RingBasePeriod = FXParam-0x80; 789 voice->vc_RingFixedPeriod = 0; 790 } else { 791 voice->vc_RingBasePeriod = 0; 792 voice->vc_RingFixedPeriod = 0; 793 voice->vc_RingNewWaveform = 0; 794 voice->vc_RingAudioSource = NULL; 795 voice->vc_RingMixSource = NULL; 796 break; 797 } 798 799 voice->vc_RingWaveform = 1; 800 voice->vc_RingNewWaveform = 1; 801 voice->vc_RingPlantPeriod = 1; 802 break; 803 804 /* New in HivelyTracker 1.4 */ 805 case 9: 806 if ( FXParam > 127 ) 807 { 808 FXParam -= 256; 809 } 810 voice->vc_Pan = (FXParam+128); 811 voice->vc_PanMultLeft = panning_left[voice->vc_Pan]; 812 voice->vc_PanMultRight = panning_right[voice->vc_Pan]; 813 break; 814 815 case 12: 816 if ( FXParam <= 0x40 ) 817 { 818 voice->vc_NoteMaxVolume = FXParam; 819 break; 820 } 821 822 if ( (FXParam -= 0x50) < 0 ) 823 { 824 break; 825 } 826 827 if ( FXParam <= 0x40 ) 828 { 829 voice->vc_PerfSubVolume = FXParam; 830 break; 831 } 832 833 if ( (FXParam -= 0xa0-0x50) < 0 ) 834 { 835 break; 836 } 837 838 if ( FXParam <= 0x40 ) 839 { 840 voice->vc_TrackMasterVolume = FXParam; 841 } 842 break; 843 844 case 15: 845 voice->vc_PerfSpeed = voice->vc_PerfWait = FXParam; 846 break; 847 } 848 } 849 850 static void hvl_process_frame ( struct hvl_tune *ht, struct hvl_voice *voice ) 851 { 852 static const uint8_t Offsets[] = { 853 0x00, 854 0x04, 855 0x04 + 0x08, 856 0x04 + 0x08 + 0x10, 857 0x04 + 0x08 + 0x10 + 0x20, 858 0x04 + 0x08 + 0x10 + 0x20 + 0x40 859 }; 860 861 if ( voice->vc_TrackOn == 0 ) 862 { 863 return; 864 } 865 866 if ( voice->vc_NoteDelayOn ) 867 { 868 if ( voice->vc_NoteDelayWait <= 0 ) 869 { 870 hvl_process_step ( ht, voice ); 871 } else { 872 voice->vc_NoteDelayWait--; 873 } 874 } 875 876 if ( voice->vc_HardCut ) 877 { 878 int32_t nextinst; 879 880 if ( ht->ht_NoteNr+1 < ht->ht_TrackLength ) 881 { 882 nextinst = ht->ht_Tracks[voice->vc_Track][ht->ht_NoteNr+1].stp_Instrument; 883 } else { 884 nextinst = ht->ht_Tracks[voice->vc_NextTrack][0].stp_Instrument; 885 } 886 887 if ( nextinst ) 888 { 889 int32_t d1; 890 891 d1 = ht->ht_Tempo - voice->vc_HardCut; 892 893 if ( d1 < 0 ) 894 { 895 d1 = 0; 896 } 897 898 if ( !voice->vc_NoteCutOn ) 899 { 900 voice->vc_NoteCutOn = 1; 901 voice->vc_NoteCutWait = d1; 902 voice->vc_HardCutReleaseF = -(d1-ht->ht_Tempo); 903 } else { 904 voice->vc_HardCut = 0; 905 } 906 } 907 } 908 909 if ( voice->vc_NoteCutOn ) 910 { 911 if ( voice->vc_NoteCutWait <= 0 ) 912 { 913 voice->vc_NoteCutOn = 0; 914 915 if ( voice->vc_HardCutRelease ) 916 { 917 voice->vc_ADSR.rVolume = -(voice->vc_ADSRVolume - (voice->vc_Instrument->ins_Envelope.rVolume << 8)) / voice->vc_HardCutReleaseF; 918 voice->vc_ADSR.rFrames = voice->vc_HardCutReleaseF; 919 voice->vc_ADSR.aFrames = voice->vc_ADSR.dFrames = voice->vc_ADSR.sFrames = 0; 920 } else { 921 voice->vc_NoteMaxVolume = 0; 922 } 923 } else { 924 voice->vc_NoteCutWait--; 925 } 926 } 927 928 // ADSR envelope 929 if ( voice->vc_ADSR.aFrames ) 930 { 931 voice->vc_ADSRVolume += voice->vc_ADSR.aVolume; 932 933 if ( --voice->vc_ADSR.aFrames <= 0 ) 934 { 935 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.aVolume << 8; 936 } 937 } else if ( voice->vc_ADSR.dFrames ) 938 { 939 voice->vc_ADSRVolume += voice->vc_ADSR.dVolume; 940 941 if ( --voice->vc_ADSR.dFrames <= 0 ) 942 { 943 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.dVolume << 8; 944 } 945 } else if ( voice->vc_ADSR.sFrames ) 946 { 947 voice->vc_ADSR.sFrames--; 948 } else if ( voice->vc_ADSR.rFrames ) 949 { 950 voice->vc_ADSRVolume += voice->vc_ADSR.rVolume; 951 952 if ( --voice->vc_ADSR.rFrames <= 0 ) 953 { 954 voice->vc_ADSRVolume = voice->vc_Instrument->ins_Envelope.rVolume << 8; 955 } 956 } 957 958 // VolumeSlide 959 voice->vc_NoteMaxVolume = voice->vc_NoteMaxVolume + voice->vc_VolumeSlideUp - voice->vc_VolumeSlideDown; 960 961 if ( voice->vc_NoteMaxVolume < 0 ) 962 { 963 voice->vc_NoteMaxVolume = 0; 964 } else if ( voice->vc_NoteMaxVolume > 0x40 ) 965 { 966 voice->vc_NoteMaxVolume = 0x40; 967 } 968 969 // Portamento 970 if ( voice->vc_PeriodSlideOn ) 971 { 972 if ( voice->vc_PeriodSlideWithLimit ) 973 { 974 int32_t d0, d2; 975 976 d0 = voice->vc_PeriodSlidePeriod - voice->vc_PeriodSlideLimit; 977 d2 = voice->vc_PeriodSlideSpeed; 978 979 if ( d0 > 0 ) 980 { 981 d2 = -d2; 982 } 983 984 if ( d0 ) 985 { 986 int32_t d3; 987 988 d3 = (d0 + d2) ^ d0; 989 990 if ( d3 >= 0 ) 991 { 992 d0 = voice->vc_PeriodSlidePeriod + d2; 993 } else { 994 d0 = voice->vc_PeriodSlideLimit; 995 } 996 997 voice->vc_PeriodSlidePeriod = d0; 998 voice->vc_PlantPeriod = 1; 999 } 1000 } else { 1001 voice->vc_PeriodSlidePeriod += voice->vc_PeriodSlideSpeed; 1002 voice->vc_PlantPeriod = 1; 1003 } 1004 } 1005 1006 // Vibrato 1007 if ( voice->vc_VibratoDepth ) 1008 { 1009 if ( voice->vc_VibratoDelay <= 0 ) 1010 { 1011 voice->vc_VibratoPeriod = (vib_tab[voice->vc_VibratoCurrent] * voice->vc_VibratoDepth) >> 7; 1012 voice->vc_PlantPeriod = 1; 1013 voice->vc_VibratoCurrent = (voice->vc_VibratoCurrent + voice->vc_VibratoSpeed) & 0x3f; 1014 } else { 1015 voice->vc_VibratoDelay--; 1016 } 1017 } 1018 1019 // PList 1020 if ( voice->vc_PerfList != 0 ) 1021 { 1022 if ( voice->vc_Instrument && voice->vc_PerfCurrent < voice->vc_Instrument->ins_PList.pls_Length ) 1023 { 1024 if ( --voice->vc_PerfWait <= 0 ) 1025 { 1026 uint32_t i; 1027 int32_t cur; 1028 1029 cur = voice->vc_PerfCurrent++; 1030 voice->vc_PerfWait = voice->vc_PerfSpeed; 1031 eval_windowfunction(WindowAggState * winstate,WindowStatePerFunc perfuncstate,Datum * result,bool * isnull)1032 if ( voice->vc_PerfList->pls_Entries[cur].ple_Waveform ) 1033 { 1034 voice->vc_Waveform = voice->vc_PerfList->pls_Entries[cur].ple_Waveform-1; 1035 voice->vc_NewWaveform = 1; 1036 voice->vc_PeriodPerfSlideSpeed = voice->vc_PeriodPerfSlidePeriod = 0; 1037 } 1038 1039 // Holdwave 1040 voice->vc_PeriodPerfSlideOn = 0; 1041 1042 for( i=0; i<2; i++ ) 1043 { 1044 hvl_plist_command_parse ( ht, voice, voice->vc_PerfList->pls_Entries[cur].ple_FX[i]&0xff, voice->vc_PerfList->pls_Entries[cur].ple_FXParam[i]&0xff ); 1045 } 1046 1047 // GetNote 1048 if ( voice->vc_PerfList->pls_Entries[cur].ple_Note ) 1049 { 1050 voice->vc_InstrPeriod = voice->vc_PerfList->pls_Entries[cur].ple_Note; 1051 voice->vc_PlantPeriod = 1; 1052 voice->vc_FixedNote = voice->vc_PerfList->pls_Entries[cur].ple_Fixed; 1053 } 1054 } 1055 } else { 1056 if ( voice->vc_PerfWait ) 1057 { 1058 voice->vc_PerfWait--; 1059 } else { 1060 voice->vc_PeriodPerfSlideSpeed = 0; 1061 } 1062 } 1063 } 1064 1065 // PerfPortamento 1066 if ( voice->vc_PeriodPerfSlideOn ) 1067 { 1068 voice->vc_PeriodPerfSlidePeriod -= voice->vc_PeriodPerfSlideSpeed; 1069 1070 if ( voice->vc_PeriodPerfSlidePeriod ) 1071 { 1072 voice->vc_PlantPeriod = 1; 1073 } 1074 } 1075 1076 if ( voice->vc_Waveform == 3-1 && voice->vc_SquareOn ) /* SQUARE */ 1077 { begin_partition(WindowAggState * winstate)1078 if ( --voice->vc_SquareWait <= 0 ) 1079 { 1080 int32_t d1, d2, d3; 1081 1082 d1 = voice->vc_SquareLowerLimit; 1083 d2 = voice->vc_SquareUpperLimit; 1084 d3 = voice->vc_SquarePos; 1085 1086 if ( voice->vc_SquareInit ) 1087 { 1088 voice->vc_SquareInit = 0; 1089 1090 if ( d3 <= d1 ) 1091 { 1092 voice->vc_SquareSlidingIn = 1; 1093 voice->vc_SquareSign = 1; 1094 } else if ( d3 >= d2 ) 1095 { 1096 voice->vc_SquareSlidingIn = 1; 1097 voice->vc_SquareSign = -1; 1098 } 1099 } 1100 1101 // NoSquareInit 1102 if ( d1 == d3 || d2 == d3 ) 1103 { 1104 if ( voice->vc_SquareSlidingIn ) 1105 { 1106 voice->vc_SquareSlidingIn = 0; 1107 } else { 1108 voice->vc_SquareSign = -voice->vc_SquareSign; 1109 } 1110 } 1111 1112 d3 += voice->vc_SquareSign; 1113 voice->vc_SquarePos = d3; 1114 voice->vc_PlantSquare = 1; 1115 voice->vc_SquareWait = voice->vc_Instrument->ins_SquareSpeed; 1116 } 1117 } 1118 1119 if ( voice->vc_FilterOn && --voice->vc_FilterWait <= 0 ) 1120 { 1121 uint32_t i, FMax; 1122 int32_t d1, d2, d3; 1123 1124 d1 = voice->vc_FilterLowerLimit; 1125 d2 = voice->vc_FilterUpperLimit; 1126 d3 = voice->vc_FilterPos; 1127 1128 if ( voice->vc_FilterInit ) 1129 { 1130 voice->vc_FilterInit = 0; 1131 if ( d3 <= d1 ) 1132 { 1133 voice->vc_FilterSlidingIn = 1; 1134 voice->vc_FilterSign = 1; 1135 } else if ( d3 >= d2 ) 1136 { 1137 voice->vc_FilterSlidingIn = 1; 1138 voice->vc_FilterSign = -1; 1139 } 1140 } 1141 1142 // NoFilterInit 1143 FMax = (voice->vc_FilterSpeed < 3) ? (5-voice->vc_FilterSpeed) : 1; 1144 1145 for ( i=0; i<FMax; i++ ) 1146 { 1147 if ( ( d1 == d3 ) || ( d2 == d3 ) ) 1148 { 1149 if ( voice->vc_FilterSlidingIn ) 1150 { 1151 voice->vc_FilterSlidingIn = 0; 1152 } else { 1153 voice->vc_FilterSign = -voice->vc_FilterSign; 1154 } 1155 } 1156 d3 += voice->vc_FilterSign; 1157 } 1158 1159 if( d3 < 1 ) 1160 { 1161 d3 = 1; 1162 } 1163 if( d3 > 63 ) 1164 { 1165 d3 = 63; 1166 } 1167 voice->vc_FilterPos = d3; 1168 voice->vc_NewWaveform = 1; 1169 voice->vc_FilterWait = voice->vc_FilterSpeed - 3; 1170 1171 if ( voice->vc_FilterWait < 1 ) 1172 { 1173 voice->vc_FilterWait = 1; 1174 } 1175 } 1176 1177 if ( voice->vc_Waveform == 3-1 || voice->vc_PlantSquare ) /* SQUARE */ 1178 { 1179 // CalcSquare 1180 uint32_t i; 1181 int32_t Delta; 1182 int8_t *SquarePtr; 1183 int32_t X; 1184 1185 SquarePtr = &waves[WO_SQUARES+(voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3)]; 1186 X = voice->vc_SquarePos << (5 - voice->vc_WaveLength); 1187 1188 if ( X > 0x20 ) 1189 { 1190 X = 0x40 - X; 1191 voice->vc_SquareReverse = 1; 1192 } 1193 1194 // OkDownSquare 1195 if( X > 0 ) 1196 { 1197 SquarePtr += (X-1) << 7; 1198 } 1199 1200 Delta = 32 >> voice->vc_WaveLength; 1201 ht->ht_WaveformTab[2] = voice->vc_SquareTempBuffer; 1202 1203 for ( i=0; i<(1<<voice->vc_WaveLength)*4; i++ ) 1204 { 1205 voice->vc_SquareTempBuffer[i] = *SquarePtr; 1206 SquarePtr += Delta; 1207 } 1208 1209 voice->vc_NewWaveform = 1; 1210 voice->vc_Waveform = 3-1; /* SQUARE */ 1211 voice->vc_PlantSquare = 0; 1212 } 1213 1214 if ( voice->vc_Waveform == 4-1 ) /* WHITENOISE */ 1215 { 1216 voice->vc_NewWaveform = 1; 1217 } 1218 1219 if ( voice->vc_RingNewWaveform ) 1220 { 1221 int8_t *rasrc; 1222 1223 if ( voice->vc_RingWaveform > 1 ) 1224 { 1225 voice->vc_RingWaveform = 1; 1226 } 1227 1228 rasrc = ht->ht_WaveformTab[voice->vc_RingWaveform]; /* RingWaveform is either TRIANGLE or SAWTOOTH */ 1229 rasrc += Offsets[voice->vc_WaveLength]; 1230 1231 voice->vc_RingAudioSource = rasrc; 1232 } 1233 1234 if ( voice->vc_NewWaveform ) 1235 { 1236 int8_t *AudioSource; 1237 spool_tuples(WindowAggState * winstate,int64 pos)1238 AudioSource = ht->ht_WaveformTab[voice->vc_Waveform]; 1239 1240 if ( voice->vc_Waveform != 3-1 ) /* SQUARE_WAVEFORM */ 1241 { 1242 AudioSource += (voice->vc_FilterPos-0x20)*(0xfc+0xfc+0x80*0x1f+0x80+0x280*3); 1243 } 1244 1245 if ( voice->vc_Waveform < 3-1) /* TRIANGLE or SAWTOOTH */ 1246 { 1247 // GetWLWaveformlor2 1248 AudioSource += Offsets[voice->vc_WaveLength]; 1249 } 1250 1251 if ( voice->vc_Waveform == 4-1 ) /* WHITENOISE */ 1252 { 1253 // AddRandomMoving 1254 AudioSource += ( voice->vc_WNRandom & (2*0x280-1) ) & ~1; 1255 // GoOnRandom 1256 voice->vc_WNRandom += 2239384; 1257 voice->vc_WNRandom = ((((voice->vc_WNRandom >> 8) | (voice->vc_WNRandom << 24)) + 782323) ^ 75) - 6735; 1258 } 1259 1260 voice->vc_AudioSource = AudioSource; 1261 } 1262 1263 // Ring modulation period calculation 1264 if ( voice->vc_RingAudioSource ) 1265 { 1266 voice->vc_RingAudioPeriod = voice->vc_RingBasePeriod; 1267 1268 if ( !(voice->vc_RingFixedPeriod) ) 1269 { 1270 if ( voice->vc_OverrideTranspose != 1000 ) // 1.5 1271 { 1272 voice->vc_RingAudioPeriod += voice->vc_OverrideTranspose + voice->vc_TrackPeriod - 1; 1273 } else { 1274 voice->vc_RingAudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1; 1275 } 1276 } 1277 1278 if ( voice->vc_RingAudioPeriod > 5*12 ) 1279 { 1280 voice->vc_RingAudioPeriod = 5*12; 1281 } 1282 1283 if ( voice->vc_RingAudioPeriod < 0 ) 1284 { 1285 voice->vc_RingAudioPeriod = 0; 1286 } 1287 1288 voice->vc_RingAudioPeriod = period_tab[voice->vc_RingAudioPeriod]; 1289 1290 if ( !(voice->vc_RingFixedPeriod) ) 1291 { 1292 voice->vc_RingAudioPeriod += voice->vc_PeriodSlidePeriod; 1293 } 1294 voice->vc_RingAudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod; 1295 1296 if ( voice->vc_RingAudioPeriod > 0x0d60 ) 1297 { 1298 voice->vc_RingAudioPeriod = 0x0d60; 1299 } 1300 1301 if ( voice->vc_RingAudioPeriod < 0x0071 ) 1302 { 1303 voice->vc_RingAudioPeriod = 0x0071; 1304 } 1305 } 1306 1307 // Normal period calculation 1308 voice->vc_AudioPeriod = voice->vc_InstrPeriod; 1309 1310 if ( !(voice->vc_FixedNote) ) release_partition(WindowAggState * winstate)1311 { 1312 if ( voice->vc_OverrideTranspose != 1000 ) // 1.5 1313 { 1314 voice->vc_AudioPeriod += voice->vc_OverrideTranspose + voice->vc_TrackPeriod - 1; 1315 } else { 1316 voice->vc_AudioPeriod += voice->vc_Transpose + voice->vc_TrackPeriod - 1; 1317 } 1318 } 1319 1320 if ( voice->vc_AudioPeriod > 5*12 ) 1321 { 1322 voice->vc_AudioPeriod = 5*12; 1323 } 1324 1325 if ( voice->vc_AudioPeriod < 0 ) 1326 { 1327 voice->vc_AudioPeriod = 0; 1328 } 1329 1330 voice->vc_AudioPeriod = period_tab[voice->vc_AudioPeriod]; 1331 1332 if ( !(voice->vc_FixedNote) ) 1333 { 1334 voice->vc_AudioPeriod += voice->vc_PeriodSlidePeriod; 1335 } 1336 1337 voice->vc_AudioPeriod += voice->vc_PeriodPerfSlidePeriod + voice->vc_VibratoPeriod; 1338 1339 if ( voice->vc_AudioPeriod > 0x0d60 ) 1340 { 1341 voice->vc_AudioPeriod = 0x0d60; 1342 } 1343 1344 if ( voice->vc_AudioPeriod < 0x0071 ) 1345 { 1346 voice->vc_AudioPeriod = 0x0071; 1347 } 1348 1349 voice->vc_AudioVolume = (((((((voice->vc_ADSRVolume >> 8) * voice->vc_NoteMaxVolume) >> 6) * voice->vc_PerfSubVolume) >> 6) * voice->vc_TrackMasterVolume) >> 6); 1350 } 1351 1352 static void hvl_set_audio ( struct hvl_voice *voice, double freqf ) 1353 { 1354 if ( voice->vc_TrackOn == 0 ) 1355 { 1356 voice->vc_VoiceVolume = 0; 1357 return; 1358 } 1359 1360 voice->vc_VoiceVolume = voice->vc_AudioVolume; row_is_in_frame(WindowAggState * winstate,int64 pos,TupleTableSlot * slot)1361 1362 if ( voice->vc_PlantPeriod ) 1363 { 1364 double freq2; 1365 uint32_t delta; 1366 1367 voice->vc_PlantPeriod = 0; 1368 voice->vc_VoicePeriod = voice->vc_AudioPeriod; 1369 1370 freq2 = Period2Freq( voice->vc_AudioPeriod ); 1371 delta = (uint32_t)(freq2 / freqf); 1372 1373 if ( delta > (0x280<<16) ) 1374 { 1375 delta -= (0x280<<16); 1376 } 1377 if ( delta == 0 ) 1378 { 1379 delta = 1; 1380 } 1381 voice->vc_Delta = delta; 1382 } 1383 1384 if ( voice->vc_NewWaveform ) 1385 { 1386 int8_t *src; 1387 1388 src = voice->vc_AudioSource; 1389 1390 if ( voice->vc_Waveform == 4-1 ) /* WHITENOISE */ 1391 { 1392 memcpy ( &voice->vc_VoiceBuffer[0], src, 0x280 ); 1393 } else { 1394 uint32_t i, WaveLoops; 1395 1396 WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5; 1397 1398 for ( i=0; i<WaveLoops; i++ ) 1399 { 1400 memcpy( &voice->vc_VoiceBuffer[i*4*(1<<voice->vc_WaveLength)], src, 4*(1<<voice->vc_WaveLength) ); 1401 } 1402 } 1403 1404 voice->vc_VoiceBuffer[0x280] = voice->vc_VoiceBuffer[0]; 1405 voice->vc_MixSource = voice->vc_VoiceBuffer; 1406 } 1407 1408 /* Ring Modulation */ 1409 if ( voice->vc_RingPlantPeriod ) 1410 { 1411 double freq2; 1412 uint32_t delta; 1413 1414 voice->vc_RingPlantPeriod = 0; 1415 freq2 = Period2Freq( voice->vc_RingAudioPeriod ); 1416 delta = (uint32_t)(freq2 / freqf); 1417 1418 if ( delta > (0x280<<16) ) 1419 { 1420 delta -= (0x280<<16); 1421 } 1422 if ( delta == 0 ) 1423 { 1424 delta = 1; 1425 } 1426 voice->vc_RingDelta = delta; 1427 } 1428 1429 if ( voice->vc_RingNewWaveform ) 1430 { 1431 int8_t *src; 1432 uint32_t i, WaveLoops; 1433 1434 src = voice->vc_RingAudioSource; 1435 1436 WaveLoops = (1 << (5 - voice->vc_WaveLength)) * 5; 1437 1438 for ( i=0; i<WaveLoops; i++ ) 1439 { 1440 memcpy( &voice->vc_RingVoiceBuffer[i*4*(1<<voice->vc_WaveLength)], src, 4*(1<<voice->vc_WaveLength) ); 1441 } 1442 1443 voice->vc_RingVoiceBuffer[0x280] = voice->vc_RingVoiceBuffer[0]; 1444 voice->vc_RingMixSource = voice->vc_RingVoiceBuffer; 1445 } 1446 } 1447 1448 static void hvl_play_irq ( struct hvl_tune *ht ) 1449 { 1450 uint32_t i; 1451 1452 if ( ht->ht_StepWaitFrames <= 0 ) 1453 { 1454 if ( ht->ht_GetNewPosition ) 1455 { 1456 int32_t nextpos = (ht->ht_PosNr+1==ht->ht_PositionNr)?0:(ht->ht_PosNr+1); 1457 1458 for ( i=0; i<ht->ht_Channels; i++ ) 1459 { 1460 ht->ht_Voices[i].vc_Track = ht->ht_Positions[ht->ht_PosNr].pos_Track[i]; update_frameheadpos(WindowAggState * winstate)1461 ht->ht_Voices[i].vc_Transpose = ht->ht_Positions[ht->ht_PosNr].pos_Transpose[i]; 1462 ht->ht_Voices[i].vc_NextTrack = ht->ht_Positions[nextpos].pos_Track[i]; 1463 ht->ht_Voices[i].vc_NextTranspose = ht->ht_Positions[nextpos].pos_Transpose[i]; 1464 } 1465 ht->ht_GetNewPosition = 0; 1466 } 1467 1468 for ( i=0; i<ht->ht_Channels; i++ ) 1469 { 1470 hvl_process_step ( ht, &ht->ht_Voices[i] ); 1471 } 1472 1473 ht->ht_StepWaitFrames = ht->ht_Tempo; 1474 } 1475 1476 for ( i=0; i<ht->ht_Channels; i++ ) 1477 { 1478 hvl_process_frame ( ht, &ht->ht_Voices[i] ); 1479 } 1480 1481 ht->ht_PlayingTime++; 1482 if ( ht->ht_Tempo > 0 && --ht->ht_StepWaitFrames <= 0 ) 1483 { 1484 if ( !ht->ht_PatternBreak ) 1485 { 1486 ht->ht_NoteNr++; 1487 if ( ht->ht_NoteNr >= ht->ht_TrackLength ) 1488 { 1489 ht->ht_PosJump = ht->ht_PosNr+1; 1490 ht->ht_PosJumpNote = 0; 1491 ht->ht_PatternBreak = 1; 1492 } 1493 } 1494 1495 if ( ht->ht_PatternBreak ) 1496 { 1497 ht->ht_PatternBreak = 0; 1498 ht->ht_PosNr = ht->ht_PosJump; 1499 ht->ht_NoteNr = ht->ht_PosJumpNote; 1500 if ( ht->ht_PosNr == ht->ht_PositionNr ) 1501 { 1502 ht->ht_SongEndReached = 1; 1503 ht->ht_PosNr = ht->ht_Restart; 1504 } 1505 ht->ht_PosJumpNote = 0; 1506 ht->ht_PosJump = 0; 1507 1508 ht->ht_GetNewPosition = 1; 1509 } 1510 } 1511 1512 for ( i=0; i<ht->ht_Channels; i++ ) 1513 { 1514 hvl_set_audio ( &ht->ht_Voices[i], ht->ht_Frequency ); 1515 } 1516 } 1517 1518 static void 1519 hvl_mixchunk (struct hvl_tune *ht, int16_t *buf, size_t samples) 1520 { 1521 int8_t *src[MAX_CHANNELS]; 1522 int8_t *rsrc[MAX_CHANNELS]; 1523 uint32_t delta[MAX_CHANNELS]; 1524 uint32_t rdelta[MAX_CHANNELS]; 1525 int32_t vol[MAX_CHANNELS]; 1526 uint32_t pos[MAX_CHANNELS]; 1527 uint32_t rpos[MAX_CHANNELS]; 1528 uint32_t cnt; 1529 int32_t panl[MAX_CHANNELS]; 1530 int32_t panr[MAX_CHANNELS]; 1531 // uint32_t vu[MAX_CHANNELS]; 1532 int32_t j; 1533 uint32_t i, chans, loops; 1534 1535 chans = ht->ht_Channels; 1536 for ( i=0; i<chans; i++ ) 1537 { 1538 delta[i] = ht->ht_Voices[i].vc_Delta; 1539 vol[i] = ht->ht_Voices[i].vc_VoiceVolume; 1540 pos[i] = ht->ht_Voices[i].vc_SamplePos; 1541 src[i] = ht->ht_Voices[i].vc_MixSource; 1542 panl[i] = ht->ht_Voices[i].vc_PanMultLeft; 1543 panr[i] = ht->ht_Voices[i].vc_PanMultRight; 1544 1545 /* Ring Modulation */ 1546 rdelta[i]= ht->ht_Voices[i].vc_RingDelta; 1547 rpos[i] = ht->ht_Voices[i].vc_RingSamplePos; 1548 rsrc[i] = ht->ht_Voices[i].vc_RingMixSource; 1549 1550 // vu[i] = 0; 1551 } 1552 1553 do 1554 { 1555 loops = samples; 1556 for ( i=0; i<chans; i++ ) 1557 { 1558 if ( pos[i] >= (0x280 << 16)) 1559 { 1560 pos[i] -= 0x280<<16; 1561 } 1562 cnt = ((0x280<<16) - pos[i] - 1) / delta[i] + 1; 1563 if ( cnt < loops ) 1564 { 1565 loops = cnt; 1566 } 1567 1568 if ( rsrc[i] ) 1569 { 1570 if ( rpos[i] >= (0x280<<16)) 1571 { 1572 rpos[i] -= 0x280<<16; 1573 } 1574 cnt = ((0x280<<16) - rpos[i] - 1) / rdelta[i] + 1; 1575 if ( cnt < loops ) 1576 { 1577 loops = cnt; 1578 } 1579 } 1580 } 1581 1582 samples -= loops; 1583 1584 // Inner loop 1585 do 1586 { 1587 for ( i=0; i<chans; i++ ) 1588 { 1589 if ( rsrc[i] ) 1590 { 1591 /* Ring Modulation */ 1592 j = ((src[i][pos[i]>>16]*rsrc[i][rpos[i]>>16])>>7)*vol[i]; 1593 rpos[i] += rdelta[i]; 1594 } else { 1595 j = src[i][pos[i]>>16]*vol[i]; 1596 } 1597 /* 1598 if ( abs( j ) > vu[i] ) 1599 { 1600 vu[i] = abs( j ); 1601 } 1602 */ 1603 1604 *(buf++) = (j * panl[i]) >> 7; 1605 *(buf++) = (j * panr[i]) >> 7; 1606 pos[i] += delta[i]; 1607 } 1608 #if 1 1609 /* clear non-used channels, just to be nice to the caller */ 1610 for ( ; i < MAX_CHANNELS; i++) 1611 { 1612 *(buf++) = 0; 1613 *(buf++) = 0; 1614 } 1615 #else 1616 /* Possible micro-optimalization */ 1617 buf += 2 * (MAX_CHANNELS - chans); 1618 #endif 1619 1620 loops--; 1621 } while ( loops > 0 ); 1622 } while ( samples > 0 ); 1623 1624 for ( i=0; i<chans; i++ ) 1625 { 1626 ht->ht_Voices[i].vc_SamplePos = pos[i]; 1627 ht->ht_Voices[i].vc_RingSamplePos = rpos[i]; 1628 // ht->ht_Voices[i].vc_VUMeter = vu[i]; 1629 } 1630 } 1631 1632 void __attribute__ ((visibility ("internal"))) hvl_DecodeFrame (struct hvl_tune *ht, int16_t *buf, size_t buflen) 1633 { 1634 uint32_t pos = 0; 1635 uint32_t newpos; 1636 int i; 1637 1638 for(i=1; pos < buflen; i++) 1639 { 1640 hvl_play_irq ( ht ); 1641 1642 newpos = buflen * i / ht->ht_SpeedMultiplier; 1643 1644 if (newpos == pos) 1645 { 1646 continue; 1647 } 1648 hvl_mixchunk (ht, buf, newpos - pos); 1649 buf += (newpos - pos) * 2 * MAX_CHANNELS; // stereo 1650 pos = newpos; 1651 } 1652 } 1653 1654 #if 0 1655 int32_t __attribute__ ((visibility ("internal"))) hvl_mix_findloudest ( struct hvl_tune *ht, uint32_ samples ) 1656 { 1657 int8_t *src[MAX_CHANNELS]; 1658 int8_t *rsrc[MAX_CHANNELS]; 1659 uint32_t delta[MAX_CHANNELS]; 1660 uint32_t rdelta[MAX_CHANNELS]; 1661 int32_t vol[MAX_CHANNELS]; 1662 uint32_t pos[MAX_CHANNELS]; 1663 uint32_t rpos[MAX_CHANNELS]; 1664 uint32_t cnt; 1665 int32_t panl[MAX_CHANNELS]; 1666 int32_t panr[MAX_CHANNELS]; 1667 int32_t a=0, b=0, j; 1668 uint32_t loud; 1669 uint32_t i, chans, loops; 1670 1671 loud = 0; 1672 1673 chans = ht->ht_Channels; 1674 for ( i=0; i<chans; i++ ) 1675 { 1676 delta[i] = ht->ht_Voices[i].vc_Delta; 1677 vol[i] = ht->ht_Voices[i].vc_VoiceVolume; 1678 pos[i] = ht->ht_Voices[i].vc_SamplePos; 1679 src[i] = ht->ht_Voices[i].vc_MixSource; 1680 panl[i] = ht->ht_Voices[i].vc_PanMultLeft; 1681 panr[i] = ht->ht_Voices[i].vc_PanMultRight; 1682 /* Ring Modulation */ 1683 rdelta[i]= ht->ht_Voices[i].vc_RingDelta; 1684 rpos[i] = ht->ht_Voices[i].vc_RingSamplePos; 1685 rsrc[i] = ht->ht_Voices[i].vc_RingMixSource; 1686 } 1687 1688 do 1689 { 1690 loops = samples; 1691 for ( i=0; i<chans; i++ ) 1692 { 1693 if ( pos[i] >= (0x280 << 16)) 1694 { 1695 pos[i] -= 0x280<<16; 1696 } 1697 cnt = ((0x280<<16) - pos[i] - 1) / delta[i] + 1; 1698 if ( cnt < loops ) 1699 { 1700 loops = cnt; 1701 } 1702 1703 if ( rsrc[i] ) 1704 { 1705 if ( rpos[i] >= (0x280<<16)) 1706 { 1707 rpos[i] -= 0x280<<16; 1708 } 1709 cnt = ((0x280<<16) - rpos[i] - 1) / rdelta[i] + 1; 1710 if ( cnt < loops ) update_frametailpos(WindowAggState * winstate)1711 { 1712 loops = cnt; 1713 } 1714 } 1715 } 1716 1717 samples -= loops; 1718 1719 // Inner loop 1720 do 1721 { 1722 a=0; 1723 b=0; 1724 for ( i=0; i<chans; i++ ) 1725 { 1726 if ( rsrc[i] ) 1727 { 1728 /* Ring Modulation */ 1729 j = ((src[i][pos[i]>>16]*rsrc[i][rpos[i]>>16])>>7)*vol[i]; 1730 rpos[i] += rdelta[i]; 1731 } else { 1732 j = src[i][pos[i]>>16]*vol[i]; 1733 } 1734 a += (j * panl[i]) >> 7; 1735 b += (j * panr[i]) >> 7; 1736 pos[i] += delta[i]; 1737 } 1738 1739 // a = (a*ht->ht_mixgain)>>8; 1740 // b = (b*ht->ht_mixgain)>>8; 1741 a = abs ( a ); 1742 b = abs ( b ); 1743 1744 if ( a > loud ) 1745 { 1746 loud = a; 1747 } 1748 if ( b > loud ) 1749 { 1750 loud = b; 1751 } 1752 1753 loops--; 1754 } while ( loops > 0 ); 1755 } while ( samples > 0 ); 1756 1757 for ( i=0; i<chans; i++ ) 1758 { 1759 ht->ht_Voices[i].vc_SamplePos = pos[i]; 1760 ht->ht_Voices[i].vc_RingSamplePos = rpos[i]; 1761 } 1762 1763 return loud; 1764 } 1765 1766 int32_t __attribute__ ((visibility ("internal"))) hvl_FindLoudest ( struct hvl_tune *ht, int32_t maxframes, BOOL usesongend ) 1767 { 1768 uint32_t rsamp, rloop; 1769 uint32_t samples, loops, loud, n; 1770 int32_t frm; 1771 1772 rsamp = ht->ht_Frequency/50/ht->ht_SpeedMultiplier; 1773 rloop = ht->ht_SpeedMultiplier; 1774 1775 loud = 0; 1776 1777 ht->ht_SongEndReached = 0; 1778 1779 frm = 0; 1780 while ( frm < maxframes ) 1781 { 1782 if ( ( usesongend ) && ( ht->ht_SongEndReached ) ) 1783 { 1784 break; 1785 } 1786 1787 samples = rsamp; 1788 loops = rloop; 1789 1790 do 1791 { 1792 hvl_play_irq ( ht ); 1793 n = hvl_mix_findloudest ( ht, samples ); 1794 if ( n > loud ) 1795 { 1796 loud = n; 1797 } 1798 loops--; 1799 } while ( loops ); 1800 1801 frm++; 1802 } 1803 1804 return loud; 1805 } 1806 #endif 1807