trunk/src/emu/sound/ymf271.c
| r23984 | r23985 | |
| 281 | 281 | |
| 282 | 282 | st /= (double)(524288/65536); // pre-multiply with 65536 |
| 283 | 283 | |
| 284 | | slot->step = (UINT64)st; |
| 284 | slot->step = (UINT32)st; |
| 285 | 285 | } |
| 286 | 286 | else // internal waveform (FM) |
| 287 | 287 | { |
| r23984 | r23985 | |
| 293 | 293 | |
| 294 | 294 | st /= (double)(536870912/65536); // pre-multiply with 65536 |
| 295 | 295 | |
| 296 | | slot->step = (UINT64)st; |
| 296 | slot->step = (UINT32)st; |
| 297 | 297 | } |
| 298 | 298 | } |
| 299 | 299 | |
| r23984 | r23985 | |
| 420 | 420 | calculate_step(slot); |
| 421 | 421 | } |
| 422 | 422 | |
| 423 | | int ymf271_device::calculate_slot_volume(YMF271Slot *slot) |
| 423 | INT64 ymf271_device::calculate_slot_volume(YMF271Slot *slot) |
| 424 | 424 | { |
| 425 | | UINT64 volume; |
| 426 | | UINT64 env_volume; |
| 427 | | UINT64 lfo_volume = 65536; |
| 425 | INT64 volume; |
| 426 | INT64 env_volume; |
| 427 | INT64 lfo_volume = 65536; |
| 428 | 428 | |
| 429 | 429 | switch (slot->ams) |
| 430 | 430 | { |
| 431 | 431 | case 0: lfo_volume = 65536; break; // 0dB |
| 432 | | case 1: lfo_volume = 65536 - (((UINT64)slot->lfo_amplitude * 33124) >> 16); break; // 5.90625dB |
| 433 | | case 2: lfo_volume = 65536 - (((UINT64)slot->lfo_amplitude * 16742) >> 16); break; // 11.8125dB |
| 434 | | case 3: lfo_volume = 65536 - (((UINT64)slot->lfo_amplitude * 4277) >> 16); break; // 23.625dB |
| 432 | case 1: lfo_volume = 65536 - ((slot->lfo_amplitude * 33124) >> 16); break; // 5.90625dB |
| 433 | case 2: lfo_volume = 65536 - ((slot->lfo_amplitude * 16742) >> 16); break; // 11.8125dB |
| 434 | case 3: lfo_volume = 65536 - ((slot->lfo_amplitude * 4277) >> 16); break; // 23.625dB |
| 435 | 435 | } |
| 436 | 436 | |
| 437 | | env_volume = ((UINT64)env_volume_table[255 - (slot->volume >> ENV_VOLUME_SHIFT)] * (UINT64)lfo_volume) >> 16; |
| 437 | env_volume = (env_volume_table[255 - (slot->volume >> ENV_VOLUME_SHIFT)] * lfo_volume) >> 16; |
| 438 | 438 | |
| 439 | | volume = ((UINT64)env_volume * (UINT64)total_level[slot->tl]) >> 16; |
| 439 | volume = (env_volume * total_level[slot->tl]) >> 16; |
| 440 | 440 | |
| 441 | 441 | return volume; |
| 442 | 442 | } |
| r23984 | r23985 | |
| 444 | 444 | void ymf271_device::update_pcm(int slotnum, INT32 *mixp, int length) |
| 445 | 445 | { |
| 446 | 446 | int i; |
| 447 | | int final_volume; |
| 447 | INT64 final_volume; |
| 448 | 448 | INT16 sample; |
| 449 | 449 | INT64 ch0_vol, ch1_vol; //, ch2_vol, ch3_vol; |
| 450 | 450 | |
| r23984 | r23985 | |
| 481 | 481 | |
| 482 | 482 | final_volume = calculate_slot_volume(slot); |
| 483 | 483 | |
| 484 | | ch0_vol = ((UINT64)final_volume * (UINT64)channel_attenuation[slot->ch0_level]) >> 16; |
| 485 | | ch1_vol = ((UINT64)final_volume * (UINT64)channel_attenuation[slot->ch1_level]) >> 16; |
| 486 | | // ch2_vol = ((UINT64)final_volume * (UINT64)channel_attenuation[slot->ch2_level]) >> 16; |
| 487 | | // ch3_vol = ((UINT64)final_volume * (UINT64)channel_attenuation[slot->ch3_level]) >> 16; |
| 484 | ch0_vol = (final_volume * channel_attenuation[slot->ch0_level]) >> 16; |
| 485 | ch1_vol = (final_volume * channel_attenuation[slot->ch1_level]) >> 16; |
| 486 | // ch2_vol = (final_volume * channel_attenuation[slot->ch2_level]) >> 16; |
| 487 | // ch3_vol = (final_volume * channel_attenuation[slot->ch3_level]) >> 16; |
| 488 | 488 | |
| 489 | 489 | if (ch0_vol > 65536) ch0_vol = 65536; |
| 490 | 490 | if (ch1_vol > 65536) ch1_vol = 65536; |
| r23984 | r23985 | |
| 505 | 505 | // calculates 2 operator FM using algorithm 0 |
| 506 | 506 | // <--------| |
| 507 | 507 | // +--[S1]--+--[S3]--> |
| 508 | | INT32 ymf271_device::calculate_2op_fm_0(int slotnum1, int slotnum2) |
| 508 | INT64 ymf271_device::calculate_2op_fm_0(int slotnum1, int slotnum2) |
| 509 | 509 | { |
| 510 | 510 | YMF271Slot *slot1 = &m_slots[slotnum1]; |
| 511 | 511 | YMF271Slot *slot2 = &m_slots[slotnum2]; |
| r23984 | r23985 | |
| 542 | 542 | // calculates 2 operator FM using algorithm 1 |
| 543 | 543 | // <-----------------| |
| 544 | 544 | // +--[S1]--+--[S3]--|--> |
| 545 | | INT32 ymf271_device::calculate_2op_fm_1(int slotnum1, int slotnum2) |
| 545 | INT64 ymf271_device::calculate_2op_fm_1(int slotnum1, int slotnum2) |
| 546 | 546 | { |
| 547 | 547 | YMF271Slot *slot1 = &m_slots[slotnum1]; |
| 548 | 548 | YMF271Slot *slot2 = &m_slots[slotnum2]; |
| r23984 | r23985 | |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | 579 | // calculates the output of one FM operator |
| 580 | | INT32 ymf271_device::calculate_1op_fm_0(int slotnum, int phase_modulation) |
| 580 | INT64 ymf271_device::calculate_1op_fm_0(int slotnum, INT64 phase_modulation) |
| 581 | 581 | { |
| 582 | 582 | YMF271Slot *slot = &m_slots[slotnum]; |
| 583 | 583 | INT64 env; |
| r23984 | r23985 | |
| 601 | 601 | // calculates the output of one FM operator with feedback modulation |
| 602 | 602 | // <--------| |
| 603 | 603 | // +--[S1]--| |
| 604 | | INT32 ymf271_device::calculate_1op_fm_1(int slotnum) |
| 604 | INT64 ymf271_device::calculate_1op_fm_1(int slotnum) |
| 605 | 605 | { |
| 606 | 606 | YMF271Slot *slot = &m_slots[slotnum]; |
| 607 | 607 | INT64 env; |
| r23984 | r23985 | |
| 1004 | 1004 | } |
| 1005 | 1005 | } |
| 1006 | 1006 | |
| 1007 | | void ymf271_device::write_register(int slotnum, int reg, int data) |
| 1007 | void ymf271_device::write_register(int slotnum, int reg, UINT8 data) |
| 1008 | 1008 | { |
| 1009 | 1009 | YMF271Slot *slot = &m_slots[slotnum]; |
| 1010 | 1010 | |
| r23984 | r23985 | |
| 1110 | 1110 | } |
| 1111 | 1111 | } |
| 1112 | 1112 | |
| 1113 | | void ymf271_device::ymf271_write_fm(int bank, int address, int data) |
| 1113 | void ymf271_device::ymf271_write_fm(int bank, UINT8 address, UINT8 data) |
| 1114 | 1114 | { |
| 1115 | 1115 | int groupnum = fm_tab[address & 0xf]; |
| 1116 | 1116 | if (groupnum == -1) |
| r23984 | r23985 | |
| 1207 | 1207 | } |
| 1208 | 1208 | } |
| 1209 | 1209 | |
| 1210 | | void ymf271_device::ymf271_write_pcm(int data) |
| 1210 | void ymf271_device::ymf271_write_pcm(UINT8 data) |
| 1211 | 1211 | { |
| 1212 | 1212 | int slotnum = pcm_tab[m_pcmreg & 0xf]; |
| 1213 | 1213 | if (slotnum == -1) |
| r23984 | r23985 | |
| 1337 | 1337 | return m_ext_read_handler(offset); |
| 1338 | 1338 | } |
| 1339 | 1339 | |
| 1340 | | void ymf271_device::ymf271_write_timer(int data) |
| 1340 | void ymf271_device::ymf271_write_timer(UINT8 data) |
| 1341 | 1341 | { |
| 1342 | 1342 | if ((m_timerreg & 0xf0) == 0) |
| 1343 | 1343 | { |
trunk/src/emu/sound/ymf271.h
| r23984 | r23985 | |
| 40 | 40 | private: |
| 41 | 41 | struct YMF271Slot |
| 42 | 42 | { |
| 43 | | INT8 ext_en; |
| 44 | | INT8 ext_out; |
| 43 | UINT8 ext_en; |
| 44 | UINT8 ext_out; |
| 45 | 45 | UINT8 lfoFreq; |
| 46 | | INT8 lfowave; |
| 47 | | INT8 pms, ams; |
| 48 | | INT8 detune; |
| 49 | | INT8 multiple; |
| 50 | | INT8 tl; |
| 51 | | INT8 keyscale; |
| 52 | | INT8 ar; |
| 53 | | INT8 decay1rate, decay2rate; |
| 54 | | INT8 decay1lvl; |
| 55 | | INT8 relrate; |
| 56 | | INT32 fns; |
| 57 | | INT8 block; |
| 58 | | INT8 feedback; |
| 59 | | INT8 waveform; |
| 60 | | INT8 accon; |
| 61 | | INT8 algorithm; |
| 62 | | INT8 ch0_level, ch1_level, ch2_level, ch3_level; |
| 46 | UINT8 lfowave; |
| 47 | UINT8 pms, ams; |
| 48 | UINT8 detune; |
| 49 | UINT8 multiple; |
| 50 | UINT8 tl; |
| 51 | UINT8 keyscale; |
| 52 | UINT8 ar; |
| 53 | UINT8 decay1rate, decay2rate; |
| 54 | UINT8 decay1lvl; |
| 55 | UINT8 relrate; |
| 56 | UINT32 fns; |
| 57 | UINT8 block; |
| 58 | UINT8 feedback; |
| 59 | UINT8 waveform; |
| 60 | UINT8 accon; |
| 61 | UINT8 algorithm; |
| 62 | UINT8 ch0_level, ch1_level, ch2_level, ch3_level; |
| 63 | 63 | |
| 64 | 64 | UINT32 startaddr; |
| 65 | 65 | UINT32 loopaddr; |
| 66 | 66 | UINT32 endaddr; |
| 67 | | INT8 altloop; |
| 68 | | INT8 fs; |
| 69 | | INT8 srcnote, srcb; |
| 67 | UINT8 altloop; |
| 68 | UINT8 fs; |
| 69 | UINT8 srcnote, srcb; |
| 70 | 70 | |
| 71 | | INT64 step; |
| 72 | | INT64 stepptr; |
| 71 | UINT32 step; |
| 72 | UINT32 stepptr; |
| 73 | 73 | |
| 74 | | INT8 active; |
| 75 | | INT8 bits; |
| 74 | UINT8 active; |
| 75 | UINT8 bits; |
| 76 | 76 | |
| 77 | 77 | // envelope generator |
| 78 | 78 | INT32 volume; |
| r23984 | r23985 | |
| 85 | 85 | INT64 feedback_modulation0; |
| 86 | 86 | INT64 feedback_modulation1; |
| 87 | 87 | |
| 88 | | INT32 lfo_phase, lfo_step; |
| 89 | | INT32 lfo_amplitude; |
| 88 | int lfo_phase, lfo_step; |
| 89 | int lfo_amplitude; |
| 90 | 90 | double lfo_phasemod; |
| 91 | 91 | }; |
| 92 | 92 | |
| 93 | 93 | struct YMF271Group |
| 94 | 94 | { |
| 95 | | INT8 sync, pfm; |
| 95 | UINT8 sync, pfm; |
| 96 | 96 | }; |
| 97 | 97 | |
| 98 | 98 | void init_state(); |
| r23984 | r23985 | |
| 101 | 101 | void init_envelope(YMF271Slot *slot); |
| 102 | 102 | void init_lfo(YMF271Slot *slot); |
| 103 | 103 | void update_lfo(YMF271Slot *slot); |
| 104 | | int calculate_slot_volume(YMF271Slot *slot); |
| 104 | INT64 calculate_slot_volume(YMF271Slot *slot); |
| 105 | 105 | void update_pcm(int slotnum, INT32 *mixp, int length); |
| 106 | | INT32 calculate_2op_fm_0(int slotnum1, int slotnum2); |
| 107 | | INT32 calculate_2op_fm_1(int slotnum1, int slotnum2); |
| 108 | | INT32 calculate_1op_fm_0(int slotnum, int phase_modulation); |
| 109 | | INT32 calculate_1op_fm_1(int slotnum); |
| 110 | | void write_register(int slotnum, int reg, int data); |
| 111 | | void ymf271_write_fm(int grp, int adr, int data); |
| 112 | | void ymf271_write_pcm(int data); |
| 106 | INT64 calculate_2op_fm_0(int slotnum1, int slotnum2); |
| 107 | INT64 calculate_2op_fm_1(int slotnum1, int slotnum2); |
| 108 | INT64 calculate_1op_fm_0(int slotnum, INT64 phase_modulation); |
| 109 | INT64 calculate_1op_fm_1(int slotnum); |
| 110 | void write_register(int slotnum, int reg, UINT8 data); |
| 111 | void ymf271_write_fm(int bank, UINT8 address, UINT8 data); |
| 112 | void ymf271_write_pcm(UINT8 data); |
| 113 | 113 | UINT8 ymf271_read_memory(UINT32 offset); |
| 114 | | void ymf271_write_timer(int data); |
| 114 | void ymf271_write_timer(UINT8 data); |
| 115 | 115 | |
| 116 | 116 | // internal state |
| 117 | 117 | YMF271Slot m_slots[48]; |
| 118 | 118 | YMF271Group m_groups[12]; |
| 119 | 119 | |
| 120 | | INT32 m_timerA; |
| 121 | | INT32 m_timerB; |
| 122 | | INT32 m_irqstate; |
| 123 | | INT8 m_status; |
| 124 | | INT8 m_enable; |
| 120 | UINT32 m_timerA; |
| 121 | UINT32 m_timerB; |
| 122 | UINT8 m_irqstate; |
| 123 | UINT8 m_status; |
| 124 | UINT8 m_enable; |
| 125 | 125 | |
| 126 | | INT8 m_reg0; |
| 127 | | INT8 m_reg1; |
| 128 | | INT8 m_reg2; |
| 129 | | INT8 m_reg3; |
| 130 | | INT8 m_pcmreg; |
| 131 | | INT8 m_timerreg; |
| 126 | UINT8 m_reg0; |
| 127 | UINT8 m_reg1; |
| 128 | UINT8 m_reg2; |
| 129 | UINT8 m_reg3; |
| 130 | UINT8 m_pcmreg; |
| 131 | UINT8 m_timerreg; |
| 132 | 132 | UINT32 m_ext_address; |
| 133 | 133 | UINT8 m_ext_rw; |
| 134 | 134 | UINT8 m_ext_readlatch; |