trunk/src/emu/sound/ymf271.c
| r23992 | r23993 | |
| 20 | 20 | - ch2/ch3 (4 speakers) |
| 21 | 21 | - PFM (FM using external PCM waveform) |
| 22 | 22 | - detune |
| 23 | | - Acc On bit |
| 23 | - Acc On bit (some sound effects in viprp1?) |
| 24 | 24 | - Is memory handling 100% correct? At the moment, seibuspi.c is the only |
| 25 | 25 | hardware currently emulated that uses external handlers. |
| 26 | 26 | */ |
| r23992 | r23993 | |
| 28 | 28 | #include "emu.h" |
| 29 | 29 | #include "ymf271.h" |
| 30 | 30 | |
| 31 | #define STD_CLOCK (16934400) |
| 32 | |
| 31 | 33 | #define MAXOUT (+32767) |
| 32 | 34 | #define MINOUT (-32768) |
| 33 | 35 | |
| r23992 | r23993 | |
| 42 | 44 | #define ALFO_MAX (+65536) |
| 43 | 45 | #define ALFO_MIN (0) |
| 44 | 46 | |
| 45 | | // slot mapping assists |
| 46 | | static const int fm_tab[16] = { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1 }; |
| 47 | | static const int pcm_tab[16] = { 0, 4, 8, -1, 12, 16, 20, -1, 24, 28, 32, -1, 36, 40, 44, -1 }; |
| 48 | | |
| 49 | | static INT16 wavetable[8][SIN_LEN]; |
| 50 | | static double plfo_table[4][8][LFO_LENGTH]; |
| 51 | | static int alfo_table[4][LFO_LENGTH]; |
| 52 | | |
| 53 | 47 | #define ENV_ATTACK 0 |
| 54 | 48 | #define ENV_DECAY1 1 |
| 55 | 49 | #define ENV_DECAY2 2 |
| r23992 | r23993 | |
| 185 | 179 | { 0, 3, 7, 15, 31, 31, 31, 31 }, |
| 186 | 180 | }; |
| 187 | 181 | |
| 182 | static const double multiple_table[16] = { 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
| 183 | |
| 184 | static const double pow_table[16] = { 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 0.5, 1, 2, 4, 8, 16, 32, 64 }; |
| 185 | |
| 186 | static const double fs_frequency[4] = { 1.0/1.0, 1.0/2.0, 1.0/4.0, 1.0/8.0 }; |
| 187 | |
| 188 | 188 | static const double channel_attenuation_table[16] = |
| 189 | 189 | { |
| 190 | 190 | 0.0, 2.5, 6.0, 8.5, 12.0, 14.5, 18.1, 20.6, 24.1, 26.6, 30.1, 32.6, 36.1, 96.1, 96.1, 96.1 |
| r23992 | r23993 | |
| 195 | 195 | // feedback_level * 16 |
| 196 | 196 | static const int feedback_level[8] = { 0, 1, 2, 4, 8, 16, 32, 64 }; |
| 197 | 197 | |
| 198 | | static int channel_attenuation[16]; |
| 199 | | static int total_level[128]; |
| 200 | | static int env_volume_table[256]; |
| 198 | // slot mapping assists |
| 199 | static const int fm_tab[16] = { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1 }; |
| 200 | static const int pcm_tab[16] = { 0, 4, 8, -1, 12, 16, 20, -1, 24, 28, 32, -1, 36, 40, 44, -1 }; |
| 201 | 201 | |
| 202 | 202 | |
| 203 | /*****************************************************************************/ |
| 204 | |
| 203 | 205 | INLINE int GET_KEYSCALED_RATE(int rate, int keycode, int keyscale) |
| 204 | 206 | { |
| 205 | 207 | int newrate = rate + RKS_Table[keycode][keyscale]; |
| r23992 | r23993 | |
| 261 | 263 | return ((block & 7) * 4) + n43; |
| 262 | 264 | } |
| 263 | 265 | |
| 264 | | static const double multiple_table[16] = { 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
| 265 | | |
| 266 | | static const double pow_table[16] = { 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 0.5, 1, 2, 4, 8, 16, 32, 64 }; |
| 267 | | |
| 268 | | static const double fs_frequency[4] = { 1.0/1.0, 1.0/2.0, 1.0/4.0, 1.0/8.0 }; |
| 269 | | |
| 270 | 266 | void ymf271_device::calculate_step(YMF271Slot *slot) |
| 271 | 267 | { |
| 272 | 268 | double st; |
| r23992 | r23993 | |
| 356 | 352 | int keycode, rate; |
| 357 | 353 | int decay_level = 255 - (slot->decay1lvl << 4); |
| 358 | 354 | |
| 359 | | double time; |
| 360 | | |
| 361 | 355 | if (slot->waveform != 7) |
| 362 | 356 | { |
| 363 | 357 | keycode = GET_INTERNAL_KEYCODE(slot->block, slot->fns); |
| r23992 | r23993 | |
| 370 | 364 | |
| 371 | 365 | // init attack state |
| 372 | 366 | rate = GET_KEYSCALED_RATE(slot->ar * 2, keycode, slot->keyscale); |
| 373 | | time = (ARTime[rate] * 44100.0) / 1000.0; // attack end time in samples |
| 374 | | slot->env_attack_step = time < 0 ? 0 : (int)(((double)(255-0) / time) * 65536.0); |
| 367 | slot->env_attack_step = (rate < 4) ? 0 : (int)(((double)(255-0) / m_lut_ar[rate]) * 65536.0); |
| 375 | 368 | |
| 376 | 369 | // init decay1 state |
| 377 | 370 | rate = GET_KEYSCALED_RATE(slot->decay1rate * 2, keycode, slot->keyscale); |
| 378 | | time = (DCTime[rate] * 44100.0) / 1000.0; |
| 379 | | slot->env_decay1_step = time < 0 ? 0 : (int)(((double)(255-decay_level) / time) * 65536.0); |
| 371 | slot->env_decay1_step = (rate < 4) ? 0 : (int)(((double)(255-decay_level) / m_lut_dc[rate]) * 65536.0); |
| 380 | 372 | |
| 381 | 373 | // init decay2 state |
| 382 | 374 | rate = GET_KEYSCALED_RATE(slot->decay2rate * 2, keycode, slot->keyscale); |
| 383 | | time = (DCTime[rate] * 44100.0) / 1000.0; |
| 384 | | slot->env_decay2_step = time < 0 ? 0 : (int)(((double)(255-0) / time) * 65536.0); |
| 375 | slot->env_decay2_step = (rate < 4) ? 0 : (int)(((double)(255-0) / m_lut_dc[rate]) * 65536.0); |
| 385 | 376 | |
| 386 | 377 | // init release state |
| 387 | 378 | rate = GET_KEYSCALED_RATE(slot->relrate * 4, keycode, slot->keyscale); |
| 388 | | time = (ARTime[rate] * 44100.0) / 1000.0; |
| 389 | | slot->env_release_step = time < 0 ? 0 : (int)(((double)(255-0) / time) * 65536.0); |
| 379 | slot->env_release_step = (rate < 4) ? 0 : (int)(((double)(255-0) / m_lut_ar[rate]) * 65536.0); |
| 390 | 380 | |
| 391 | 381 | slot->volume = (255-160) << ENV_VOLUME_SHIFT; // -60db |
| 392 | 382 | slot->env_state = ENV_ATTACK; |
| r23992 | r23993 | |
| 398 | 388 | slot->lfo_amplitude = 0; |
| 399 | 389 | slot->lfo_phasemod = 0; |
| 400 | 390 | |
| 401 | | slot->lfo_step = (int)((((double)LFO_LENGTH * LFO_frequency_table[slot->lfoFreq]) / 44100.0) * 256.0); |
| 391 | slot->lfo_step = (int)((((double)LFO_LENGTH * m_lut_lfo[slot->lfoFreq]) / 44100.0) * 256.0); |
| 402 | 392 | } |
| 403 | 393 | |
| 404 | 394 | void ymf271_device::update_lfo(YMF271Slot *slot) |
| 405 | 395 | { |
| 406 | 396 | slot->lfo_phase += slot->lfo_step; |
| 407 | 397 | |
| 408 | | slot->lfo_amplitude = alfo_table[slot->lfowave][(slot->lfo_phase >> LFO_SHIFT) & (LFO_LENGTH-1)]; |
| 409 | | slot->lfo_phasemod = plfo_table[slot->lfowave][slot->pms][(slot->lfo_phase >> LFO_SHIFT) & (LFO_LENGTH-1)]; |
| 398 | slot->lfo_amplitude = m_lut_alfo[slot->lfowave][(slot->lfo_phase >> LFO_SHIFT) & (LFO_LENGTH-1)]; |
| 399 | slot->lfo_phasemod = m_lut_plfo[slot->lfowave][slot->pms][(slot->lfo_phase >> LFO_SHIFT) & (LFO_LENGTH-1)]; |
| 410 | 400 | |
| 411 | 401 | calculate_step(slot); |
| 412 | 402 | } |
| r23992 | r23993 | |
| 425 | 415 | case 3: lfo_volume = 65536 - ((slot->lfo_amplitude * 4277) >> 16); break; // 23.625dB |
| 426 | 416 | } |
| 427 | 417 | |
| 428 | | env_volume = (env_volume_table[255 - (slot->volume >> ENV_VOLUME_SHIFT)] * lfo_volume) >> 16; |
| 418 | env_volume = (m_lut_env_volume[255 - (slot->volume >> ENV_VOLUME_SHIFT)] * lfo_volume) >> 16; |
| 429 | 419 | |
| 430 | | volume = (env_volume * total_level[slot->tl]) >> 16; |
| 420 | volume = (env_volume * m_lut_total_level[slot->tl]) >> 16; |
| 431 | 421 | |
| 432 | 422 | return volume; |
| 433 | 423 | } |
| r23992 | r23993 | |
| 472 | 462 | |
| 473 | 463 | final_volume = calculate_slot_volume(slot); |
| 474 | 464 | |
| 475 | | ch0_vol = (final_volume * channel_attenuation[slot->ch0_level]) >> 16; |
| 476 | | ch1_vol = (final_volume * channel_attenuation[slot->ch1_level]) >> 16; |
| 477 | | // ch2_vol = (final_volume * channel_attenuation[slot->ch2_level]) >> 16; |
| 478 | | // ch3_vol = (final_volume * channel_attenuation[slot->ch3_level]) >> 16; |
| 465 | ch0_vol = (final_volume * m_lut_attenuation[slot->ch0_level]) >> 16; |
| 466 | ch1_vol = (final_volume * m_lut_attenuation[slot->ch1_level]) >> 16; |
| 467 | // ch2_vol = (final_volume * m_lut_attenuation[slot->ch2_level]) >> 16; |
| 468 | // ch3_vol = (final_volume * m_lut_attenuation[slot->ch3_level]) >> 16; |
| 479 | 469 | |
| 480 | 470 | if (ch0_vol > 65536) ch0_vol = 65536; |
| 481 | 471 | if (ch1_vol > 65536) ch1_vol = 65536; |
| r23992 | r23993 | |
| 515 | 505 | feedback = (slot1->feedback_modulation0 + slot1->feedback_modulation1) / 2; |
| 516 | 506 | slot1->feedback_modulation0 = slot1->feedback_modulation1; |
| 517 | 507 | |
| 518 | | slot1_output = wavetable[slot1->waveform][((slot1->stepptr + feedback) >> 16) & SIN_MASK]; |
| 508 | slot1_output = m_lut_waves[slot1->waveform][((slot1->stepptr + feedback) >> 16) & SIN_MASK]; |
| 519 | 509 | slot1_output = (slot1_output * env1) >> 16; |
| 520 | 510 | |
| 521 | 511 | phase_mod = ((slot1_output << (SIN_BITS-2)) * modulation_level[slot2->feedback]); |
| 522 | | slot2_output = wavetable[slot2->waveform][((slot2->stepptr + phase_mod) >> 16) & SIN_MASK]; |
| 512 | slot2_output = m_lut_waves[slot2->waveform][((slot2->stepptr + phase_mod) >> 16) & SIN_MASK]; |
| 523 | 513 | slot2_output = (slot2_output * env2) >> 16; |
| 524 | 514 | |
| 525 | 515 | slot1->feedback_modulation1 = (((slot1_output << (SIN_BITS-2)) * feedback_level[slot1->feedback]) / 16); |
| r23992 | r23993 | |
| 552 | 542 | feedback = (slot1->feedback_modulation0 + slot1->feedback_modulation1) / 2; |
| 553 | 543 | slot1->feedback_modulation0 = slot1->feedback_modulation1; |
| 554 | 544 | |
| 555 | | slot1_output = wavetable[slot1->waveform][((slot1->stepptr + feedback) >> 16) & SIN_MASK]; |
| 545 | slot1_output = m_lut_waves[slot1->waveform][((slot1->stepptr + feedback) >> 16) & SIN_MASK]; |
| 556 | 546 | slot1_output = (slot1_output * env1) >> 16; |
| 557 | 547 | |
| 558 | 548 | phase_mod = ((slot1_output << (SIN_BITS-2)) * modulation_level[slot2->feedback]); |
| 559 | | slot2_output = wavetable[slot2->waveform][((slot2->stepptr + phase_mod) >> 16) & SIN_MASK]; |
| 549 | slot2_output = m_lut_waves[slot2->waveform][((slot2->stepptr + phase_mod) >> 16) & SIN_MASK]; |
| 560 | 550 | slot2_output = (slot2_output * env2) >> 16; |
| 561 | 551 | |
| 562 | 552 | slot1->feedback_modulation1 = (((slot2_output << (SIN_BITS-2)) * feedback_level[slot1->feedback]) / 16); |
| r23992 | r23993 | |
| 581 | 571 | |
| 582 | 572 | phase_mod = ((phase_mod << (SIN_BITS-2)) * modulation_level[slot->feedback]); |
| 583 | 573 | |
| 584 | | slot_output = wavetable[slot->waveform][((slot->stepptr + phase_mod) >> 16) & SIN_MASK]; |
| 574 | slot_output = m_lut_waves[slot->waveform][((slot->stepptr + phase_mod) >> 16) & SIN_MASK]; |
| 585 | 575 | slot->stepptr += slot->step; |
| 586 | 576 | |
| 587 | 577 | slot_output = (slot_output * env) >> 16; |
| r23992 | r23993 | |
| 606 | 596 | feedback = slot->feedback_modulation0 + slot->feedback_modulation1; |
| 607 | 597 | slot->feedback_modulation0 = slot->feedback_modulation1; |
| 608 | 598 | |
| 609 | | slot_output = wavetable[slot->waveform][((slot->stepptr + feedback) >> 16) & SIN_MASK]; |
| 599 | slot_output = m_lut_waves[slot->waveform][((slot->stepptr + feedback) >> 16) & SIN_MASK]; |
| 610 | 600 | slot_output = (slot_output * env) >> 16; |
| 611 | 601 | |
| 612 | 602 | slot->feedback_modulation1 = (((slot_output << (SIN_BITS-2)) * feedback_level[slot->feedback]) / 16); |
| r23992 | r23993 | |
| 813 | 803 | break; |
| 814 | 804 | } |
| 815 | 805 | |
| 816 | | *mixp++ += ((output1 * channel_attenuation[m_slots[slot1].ch0_level]) + |
| 817 | | (output2 * channel_attenuation[m_slots[slot2].ch0_level]) + |
| 818 | | (output3 * channel_attenuation[m_slots[slot3].ch0_level]) + |
| 819 | | (output4 * channel_attenuation[m_slots[slot4].ch0_level])) >> 16; |
| 820 | | *mixp++ += ((output1 * channel_attenuation[m_slots[slot1].ch1_level]) + |
| 821 | | (output2 * channel_attenuation[m_slots[slot2].ch1_level]) + |
| 822 | | (output3 * channel_attenuation[m_slots[slot3].ch1_level]) + |
| 823 | | (output4 * channel_attenuation[m_slots[slot4].ch1_level])) >> 16; |
| 806 | *mixp++ += ((output1 * m_lut_attenuation[m_slots[slot1].ch0_level]) + |
| 807 | (output2 * m_lut_attenuation[m_slots[slot2].ch0_level]) + |
| 808 | (output3 * m_lut_attenuation[m_slots[slot3].ch0_level]) + |
| 809 | (output4 * m_lut_attenuation[m_slots[slot4].ch0_level])) >> 16; |
| 810 | *mixp++ += ((output1 * m_lut_attenuation[m_slots[slot1].ch1_level]) + |
| 811 | (output2 * m_lut_attenuation[m_slots[slot2].ch1_level]) + |
| 812 | (output3 * m_lut_attenuation[m_slots[slot3].ch1_level]) + |
| 813 | (output4 * m_lut_attenuation[m_slots[slot4].ch1_level])) >> 16; |
| 824 | 814 | } |
| 825 | 815 | } |
| 826 | 816 | break; |
| r23992 | r23993 | |
| 870 | 860 | break; |
| 871 | 861 | } |
| 872 | 862 | |
| 873 | | *mixp++ += ((output1 * channel_attenuation[m_slots[slot1].ch0_level]) + |
| 874 | | (output2 * channel_attenuation[m_slots[slot2].ch0_level])) >> 16; |
| 875 | | *mixp++ += ((output1 * channel_attenuation[m_slots[slot1].ch1_level]) + |
| 876 | | (output2 * channel_attenuation[m_slots[slot2].ch1_level])) >> 16; |
| 863 | *mixp++ += ((output1 * m_lut_attenuation[m_slots[slot1].ch0_level]) + |
| 864 | (output2 * m_lut_attenuation[m_slots[slot2].ch0_level])) >> 16; |
| 865 | *mixp++ += ((output1 * m_lut_attenuation[m_slots[slot1].ch1_level]) + |
| 866 | (output2 * m_lut_attenuation[m_slots[slot2].ch1_level])) >> 16; |
| 877 | 867 | } |
| 878 | 868 | } |
| 879 | 869 | } |
| r23992 | r23993 | |
| 962 | 952 | break; |
| 963 | 953 | } |
| 964 | 954 | |
| 965 | | *mixp++ += ((output1 * channel_attenuation[m_slots[slot1].ch0_level]) + |
| 966 | | (output2 * channel_attenuation[m_slots[slot2].ch0_level]) + |
| 967 | | (output3 * channel_attenuation[m_slots[slot3].ch0_level])) >> 16; |
| 968 | | *mixp++ += ((output1 * channel_attenuation[m_slots[slot1].ch1_level]) + |
| 969 | | (output2 * channel_attenuation[m_slots[slot2].ch1_level]) + |
| 970 | | (output3 * channel_attenuation[m_slots[slot3].ch1_level])) >> 16; |
| 955 | *mixp++ += ((output1 * m_lut_attenuation[m_slots[slot1].ch0_level]) + |
| 956 | (output2 * m_lut_attenuation[m_slots[slot2].ch0_level]) + |
| 957 | (output3 * m_lut_attenuation[m_slots[slot3].ch0_level])) >> 16; |
| 958 | *mixp++ += ((output1 * m_lut_attenuation[m_slots[slot1].ch1_level]) + |
| 959 | (output2 * m_lut_attenuation[m_slots[slot2].ch1_level]) + |
| 960 | (output3 * m_lut_attenuation[m_slots[slot3].ch1_level])) >> 16; |
| 971 | 961 | } |
| 972 | 962 | } |
| 973 | 963 | |
| r23992 | r23993 | |
| 1515 | 1505 | return 0; |
| 1516 | 1506 | } |
| 1517 | 1507 | |
| 1518 | | static void init_tables(running_machine &machine) |
| 1508 | void ymf271_device::init_tables() |
| 1519 | 1509 | { |
| 1520 | | int i,j; |
| 1510 | int i, j; |
| 1511 | |
| 1512 | for (i = 0; i < 8; i++) |
| 1513 | m_lut_waves[i] = auto_alloc_array(machine(), INT16, SIN_LEN); |
| 1514 | |
| 1515 | for (i = 0; i < 4*8; i++) |
| 1516 | m_lut_plfo[i>>3][i&7] = auto_alloc_array(machine(), double, LFO_LENGTH); |
| 1521 | 1517 | |
| 1522 | | for (i=0; i < SIN_LEN; i++) |
| 1518 | for (i = 0; i < 4; i++) |
| 1519 | m_lut_alfo[i] = auto_alloc_array(machine(), int, LFO_LENGTH); |
| 1520 | |
| 1521 | for (i = 0; i < SIN_LEN; i++) |
| 1523 | 1522 | { |
| 1524 | 1523 | double m = sin( ((i*2)+1) * M_PI / SIN_LEN ); |
| 1525 | 1524 | double m2 = sin( ((i*4)+1) * M_PI / SIN_LEN ); |
| 1526 | 1525 | |
| 1527 | 1526 | // Waveform 0: sin(wt) (0 <= wt <= 2PI) |
| 1528 | | wavetable[0][i] = (INT16)(m * MAXOUT); |
| 1527 | m_lut_waves[0][i] = (INT16)(m * MAXOUT); |
| 1529 | 1528 | |
| 1530 | 1529 | // Waveform 1: sin?(wt) (0 <= wt <= PI) -sin?(wt) (PI <= wt <= 2PI) |
| 1531 | | wavetable[1][i] = (i < (SIN_LEN/2)) ? (INT16)((m * m) * MAXOUT) : (INT16)((m * m) * MINOUT); |
| 1530 | m_lut_waves[1][i] = (i < (SIN_LEN/2)) ? (INT16)((m * m) * MAXOUT) : (INT16)((m * m) * MINOUT); |
| 1532 | 1531 | |
| 1533 | 1532 | // Waveform 2: sin(wt) (0 <= wt <= PI) -sin(wt) (PI <= wt <= 2PI) |
| 1534 | | wavetable[2][i] = (i < (SIN_LEN/2)) ? (INT16)(m * MAXOUT) : (INT16)(-m * MAXOUT); |
| 1533 | m_lut_waves[2][i] = (i < (SIN_LEN/2)) ? (INT16)(m * MAXOUT) : (INT16)(-m * MAXOUT); |
| 1535 | 1534 | |
| 1536 | 1535 | // Waveform 3: sin(wt) (0 <= wt <= PI) 0 |
| 1537 | | wavetable[3][i] = (i < (SIN_LEN/2)) ? (INT16)(m * MAXOUT) : 0; |
| 1536 | m_lut_waves[3][i] = (i < (SIN_LEN/2)) ? (INT16)(m * MAXOUT) : 0; |
| 1538 | 1537 | |
| 1539 | 1538 | // Waveform 4: sin(2wt) (0 <= wt <= PI) 0 |
| 1540 | | wavetable[4][i] = (i < (SIN_LEN/2)) ? (INT16)(m2 * MAXOUT) : 0; |
| 1539 | m_lut_waves[4][i] = (i < (SIN_LEN/2)) ? (INT16)(m2 * MAXOUT) : 0; |
| 1541 | 1540 | |
| 1542 | 1541 | // Waveform 5: |sin(2wt)| (0 <= wt <= PI) 0 |
| 1543 | | wavetable[5][i] = (i < (SIN_LEN/2)) ? (INT16)(fabs(m2) * MAXOUT) : 0; |
| 1542 | m_lut_waves[5][i] = (i < (SIN_LEN/2)) ? (INT16)(fabs(m2) * MAXOUT) : 0; |
| 1544 | 1543 | |
| 1545 | 1544 | // Waveform 6: 1 (0 <= wt <= 2PI) |
| 1546 | | wavetable[6][i] = (INT16)(1 * MAXOUT); |
| 1545 | m_lut_waves[6][i] = (INT16)(1 * MAXOUT); |
| 1547 | 1546 | |
| 1548 | | wavetable[7][i] = 0; |
| 1547 | m_lut_waves[7][i] = 0; |
| 1549 | 1548 | } |
| 1550 | 1549 | |
| 1551 | | for (i=0; i < LFO_LENGTH; i++) |
| 1550 | for (i = 0; i < LFO_LENGTH; i++) |
| 1552 | 1551 | { |
| 1553 | 1552 | int tri_wave; |
| 1554 | 1553 | double ftri_wave, fsaw_wave; |
| r23992 | r23993 | |
| 1569 | 1568 | case 1: plfo[3] = PLFO_MAX - ftri_wave; break; |
| 1570 | 1569 | case 2: plfo[3] = 0 - ftri_wave; break; |
| 1571 | 1570 | case 3: plfo[3] = 0 - (PLFO_MAX - ftri_wave); break; |
| 1572 | | default: plfo[3]=0; assert(0); break; |
| 1571 | default: plfo[3] = 0; assert(0); break; |
| 1573 | 1572 | } |
| 1574 | 1573 | |
| 1575 | | for (j=0; j < 4; j++) |
| 1574 | for (j = 0; j < 4; j++) |
| 1576 | 1575 | { |
| 1577 | | plfo_table[j][0][i] = pow(2.0, 0.0); |
| 1578 | | plfo_table[j][1][i] = pow(2.0, (3.378 * plfo[j]) / 1200.0); |
| 1579 | | plfo_table[j][2][i] = pow(2.0, (5.0646 * plfo[j]) / 1200.0); |
| 1580 | | plfo_table[j][3][i] = pow(2.0, (6.7495 * plfo[j]) / 1200.0); |
| 1581 | | plfo_table[j][4][i] = pow(2.0, (10.1143 * plfo[j]) / 1200.0); |
| 1582 | | plfo_table[j][5][i] = pow(2.0, (20.1699 * plfo[j]) / 1200.0); |
| 1583 | | plfo_table[j][6][i] = pow(2.0, (40.1076 * plfo[j]) / 1200.0); |
| 1584 | | plfo_table[j][7][i] = pow(2.0, (79.307 * plfo[j]) / 1200.0); |
| 1576 | m_lut_plfo[j][0][i] = pow(2.0, 0.0); |
| 1577 | m_lut_plfo[j][1][i] = pow(2.0, (3.378 * plfo[j]) / 1200.0); |
| 1578 | m_lut_plfo[j][2][i] = pow(2.0, (5.0646 * plfo[j]) / 1200.0); |
| 1579 | m_lut_plfo[j][3][i] = pow(2.0, (6.7495 * plfo[j]) / 1200.0); |
| 1580 | m_lut_plfo[j][4][i] = pow(2.0, (10.1143 * plfo[j]) / 1200.0); |
| 1581 | m_lut_plfo[j][5][i] = pow(2.0, (20.1699 * plfo[j]) / 1200.0); |
| 1582 | m_lut_plfo[j][6][i] = pow(2.0, (40.1076 * plfo[j]) / 1200.0); |
| 1583 | m_lut_plfo[j][7][i] = pow(2.0, (79.307 * plfo[j]) / 1200.0); |
| 1585 | 1584 | } |
| 1586 | 1585 | |
| 1587 | 1586 | // LFO amplitude modulation |
| 1588 | | alfo_table[0][i] = 0; |
| 1587 | m_lut_alfo[0][i] = 0; |
| 1589 | 1588 | |
| 1590 | | alfo_table[1][i] = ALFO_MAX - ((i * ALFO_MAX) / LFO_LENGTH); |
| 1589 | m_lut_alfo[1][i] = ALFO_MAX - ((i * ALFO_MAX) / LFO_LENGTH); |
| 1591 | 1590 | |
| 1592 | | alfo_table[2][i] = (i < (LFO_LENGTH/2)) ? ALFO_MAX : ALFO_MIN; |
| 1591 | m_lut_alfo[2][i] = (i < (LFO_LENGTH/2)) ? ALFO_MAX : ALFO_MIN; |
| 1593 | 1592 | |
| 1594 | 1593 | tri_wave = ((i % (LFO_LENGTH/2)) * ALFO_MAX) / (LFO_LENGTH/2); |
| 1595 | | alfo_table[3][i] = (i < (LFO_LENGTH/2)) ? ALFO_MAX-tri_wave : tri_wave; |
| 1594 | m_lut_alfo[3][i] = (i < (LFO_LENGTH/2)) ? ALFO_MAX-tri_wave : tri_wave; |
| 1596 | 1595 | } |
| 1596 | |
| 1597 | for (i = 0; i < 256; i++) |
| 1598 | { |
| 1599 | m_lut_env_volume[i] = (int)(65536.0 / pow(10.0, ((double)i / (256.0 / 96.0)) / 20.0)); |
| 1600 | } |
| 1601 | |
| 1602 | for (i = 0; i < 16; i++) |
| 1603 | { |
| 1604 | m_lut_attenuation[i] = (int)(65536.0 / pow(10.0, channel_attenuation_table[i] / 20.0)); |
| 1605 | } |
| 1606 | for (i = 0; i < 128; i++) |
| 1607 | { |
| 1608 | double db = 0.75 * (double)i; |
| 1609 | m_lut_total_level[i] = (int)(65536.0 / pow(10.0, db / 20.0)); |
| 1610 | } |
| 1611 | |
| 1612 | // timing may use a non-standard XTAL |
| 1613 | double clock_correction = (double)(STD_CLOCK) / (double)(m_clock); |
| 1614 | for (i = 0; i < 256; i++) |
| 1615 | { |
| 1616 | m_lut_lfo[i] = LFO_frequency_table[i] * clock_correction; |
| 1617 | } |
| 1618 | |
| 1619 | for (i = 0; i < 64; i++) |
| 1620 | { |
| 1621 | // attack/release rate in number of samples |
| 1622 | m_lut_ar[i] = (ARTime[i] * clock_correction * 44100.0) / 1000.0; |
| 1623 | } |
| 1624 | for (i = 0; i < 64; i++) |
| 1625 | { |
| 1626 | // decay rate in number of samples |
| 1627 | m_lut_dc[i] = (DCTime[i] * clock_correction * 44100.0) / 1000.0; |
| 1628 | } |
| 1597 | 1629 | } |
| 1598 | 1630 | |
| 1599 | 1631 | void ymf271_device::init_state() |
| r23992 | r23993 | |
| 1678 | 1710 | |
| 1679 | 1711 | void ymf271_device::device_start() |
| 1680 | 1712 | { |
| 1681 | | int i; |
| 1682 | | |
| 1683 | 1713 | m_clock = clock(); |
| 1684 | 1714 | |
| 1685 | 1715 | m_timA = timer_alloc(0); |
| r23992 | r23993 | |
| 1692 | 1722 | m_ext_read_handler.resolve(); |
| 1693 | 1723 | m_ext_write_handler.resolve(); |
| 1694 | 1724 | |
| 1695 | | init_tables(machine()); |
| 1725 | init_tables(); |
| 1696 | 1726 | init_state(); |
| 1697 | 1727 | |
| 1698 | 1728 | m_stream = machine().sound().stream_alloc(*this, 0, 2, clock()/384); |
| 1699 | 1729 | m_mix_buffer = auto_alloc_array(machine(), INT32, 44100*2); |
| 1700 | | |
| 1701 | | for (i = 0; i < 256; i++) |
| 1702 | | { |
| 1703 | | env_volume_table[i] = (int)(65536.0 / pow(10.0, ((double)i / (256.0 / 96.0)) / 20.0)); |
| 1704 | | } |
| 1705 | | |
| 1706 | | for (i = 0; i < 16; i++) |
| 1707 | | { |
| 1708 | | channel_attenuation[i] = (int)(65536.0 / pow(10.0, channel_attenuation_table[i] / 20.0)); |
| 1709 | | } |
| 1710 | | for (i = 0; i < 128; i++) |
| 1711 | | { |
| 1712 | | double db = 0.75 * (double)i; |
| 1713 | | total_level[i] = (int)(65536.0 / pow(10.0, db / 20.0)); |
| 1714 | | } |
| 1715 | 1730 | } |
| 1716 | 1731 | |
| 1717 | 1732 | //------------------------------------------------- |