diff options
author | mooglyguy <therealmogminer@gmail.com> | 2019-11-13 21:13:10 +0100 |
---|---|---|
committer | mooglyguy <therealmogminer@gmail.com> | 2019-11-13 21:15:03 +0100 |
commit | 0ced158f31196b6b2fa873affcdd7f911d356cde (patch) | |
tree | 64f97552e3f301c7ab7585b4741580e12ed7259c /src/devices/sound | |
parent | 43637964a2389cfe6288facc09cd7faaf612d4f4 (diff) |
-k007232: Added optional WAV logging of PCM samples. [Ryan Holtz]
Diffstat (limited to 'src/devices/sound')
-rw-r--r-- | src/devices/sound/k007232.cpp | 447 | ||||
-rw-r--r-- | src/devices/sound/k007232.h | 10 |
2 files changed, 152 insertions, 305 deletions
diff --git a/src/devices/sound/k007232.cpp b/src/devices/sound/k007232.cpp index 96f89ff628f..485d9f3fe5f 100644 --- a/src/devices/sound/k007232.cpp +++ b/src/devices/sound/k007232.cpp @@ -6,144 +6,29 @@ /* Changelog, Hiromitsu Shioya 02/05/2002 - fix start address decode timing. (sample loop bug.) + fixed start address decode timing. (sample loop bug.) - Changelog, Mish, August 1999: - Removed interface support for different memory regions per channel. - Removed interface support for differing channel volume. + Changelog, Mish, August 1999: + Removed interface support for different memory regions per channel. + Removed interface support for differing channel volume. - Added bankswitching. - Added support for multiple chips. + Added bankswitching. + Added support for multiple chips. - (Nb: Should different memory regions per channel be needed - the bankswitching function can set this up). - -NS990821 -support for the k007232_VOL() macro. -added external port callback, and functions to set the volume of the channels + (NB: Should different memory regions per channel be needed, the bankswitching function can set this up). + Chanelog, Nicola, August 1999: + Added Support for the k007232_VOL() macro. + Added external port callback, and functions to set the volume of the channels */ #include "emu.h" #include "k007232.h" +#include "wavwrite.h" -#define BASE_SHIFT (12) - - -#if 0 -static const int kdac_note[] = { - 261.63/8, 277.18/8, - 293.67/8, 311.13/8, - 329.63/8, - 349.23/8, 369.99/8, - 392.00/8, 415.31/8, - 440.00/8, 466.16/8, - 493.88/8, - - 523.25/8, -}; - -static const float kdaca_fn[][2] = { - /* B */ - { 0x03f, 493.88/8 }, /* ?? */ - { 0x11f, 493.88/4 }, /* ?? */ - { 0x18f, 493.88/2 }, /* ?? */ - { 0x1c7, 493.88 }, - { 0x1e3, 493.88*2 }, - { 0x1f1, 493.88*4 }, /* ?? */ - { 0x1f8, 493.88*8 }, /* ?? */ - /* A+ */ - { 0x020, 466.16/8 }, /* ?? */ - { 0x110, 466.16/4 }, /* ?? */ - { 0x188, 466.16/2 }, - { 0x1c4, 466.16 }, - { 0x1e2, 466.16*2 }, - { 0x1f1, 466.16*4 }, /* ?? */ - { 0x1f8, 466.16*8 }, /* ?? */ - /* A */ - { 0x000, 440.00/8 }, /* ?? */ - { 0x100, 440.00/4 }, /* ?? */ - { 0x180, 440.00/2 }, - { 0x1c0, 440.00 }, - { 0x1e0, 440.00*2 }, - { 0x1f0, 440.00*4 }, /* ?? */ - { 0x1f8, 440.00*8 }, /* ?? */ - { 0x1fc, 440.00*16}, /* ?? */ - { 0x1fe, 440.00*32}, /* ?? */ - { 0x1ff, 440.00*64}, /* ?? */ - /* G+ */ - { 0x0f2, 415.31/4 }, - { 0x179, 415.31/2 }, - { 0x1bc, 415.31 }, - { 0x1de, 415.31*2 }, - { 0x1ef, 415.31*4 }, /* ?? */ - { 0x1f7, 415.31*8 }, /* ?? */ - /* G */ - { 0x0e2, 392.00/4 }, - { 0x171, 392.00/2 }, - { 0x1b8, 392.00 }, - { 0x1dc, 392.00*2 }, - { 0x1ee, 392.00*4 }, /* ?? */ - { 0x1f7, 392.00*8 }, /* ?? */ - /* F+ */ - { 0x0d0, 369.99/4 }, /* ?? */ - { 0x168, 369.99/2 }, - { 0x1b4, 369.99 }, - { 0x1da, 369.99*2 }, - { 0x1ed, 369.99*4 }, /* ?? */ - { 0x1f6, 369.99*8 }, /* ?? */ - /* F */ - { 0x0bf, 349.23/4 }, /* ?? */ - { 0x15f, 349.23/2 }, - { 0x1af, 349.23 }, - { 0x1d7, 349.23*2 }, - { 0x1eb, 349.23*4 }, /* ?? */ - { 0x1f5, 349.23*8 }, /* ?? */ - /* E */ - { 0x0ac, 329.63/4 }, - { 0x155, 329.63/2 }, /* ?? */ - { 0x1ab, 329.63 }, - { 0x1d5, 329.63*2 }, - { 0x1ea, 329.63*4 }, /* ?? */ - { 0x1f4, 329.63*8 }, /* ?? */ - /* D+ */ - { 0x098, 311.13/4 }, /* ?? */ - { 0x14c, 311.13/2 }, - { 0x1a6, 311.13 }, - { 0x1d3, 311.13*2 }, - { 0x1e9, 311.13*4 }, /* ?? */ - { 0x1f4, 311.13*8 }, /* ?? */ - /* D */ - { 0x080, 293.67/4 }, /* ?? */ - { 0x140, 293.67/2 }, /* ?? */ - { 0x1a0, 293.67 }, - { 0x1d0, 293.67*2 }, - { 0x1e8, 293.67*4 }, /* ?? */ - { 0x1f4, 293.67*8 }, /* ?? */ - { 0x1fa, 293.67*16}, /* ?? */ - { 0x1fd, 293.67*32}, /* ?? */ - /* C+ */ - { 0x06d, 277.18/4 }, /* ?? */ - { 0x135, 277.18/2 }, /* ?? */ - { 0x19b, 277.18 }, - { 0x1cd, 277.18*2 }, - { 0x1e6, 277.18*4 }, /* ?? */ - { 0x1f2, 277.18*8 }, /* ?? */ - /* C */ - { 0x054, 261.63/4 }, - { 0x12a, 261.63/2 }, - { 0x195, 261.63 }, - { 0x1ca, 261.63*2 }, - { 0x1e5, 261.63*4 }, - { 0x1f2, 261.63*8 }, /* ?? */ - - { -1, -1 }, -}; -#endif - -/*************************************************************/ - +#define K007232_LOG_PCM (0) +#define BASE_SHIFT (12) DEFINE_DEVICE_TYPE(K007232, k007232_device, "k007232", "K007232 PCM Controller") @@ -164,7 +49,7 @@ void k007232_device::device_start() /* Set up the chips */ m_pcmlimit = m_rom.bytes(); - m_port_write_handler.resolve(); + m_port_write_handler.resolve_safe(); for (int i = 0; i < KDAC_A_PCM_MAX; i++) { @@ -184,7 +69,7 @@ void k007232_device::device_start() m_stream = machine().sound().stream_alloc(*this, 0 , 2, clock()/128); - KDAC_A_make_fncode(); + make_fncodes(); save_item(NAME(m_vol)); save_item(NAME(m_addr)); @@ -195,153 +80,104 @@ void k007232_device::device_start() save_item(NAME(m_wreg)); } -void k007232_device::KDAC_A_make_fncode() +void k007232_device::make_fncodes() { -#if 0 - int i, j, k; - float fn; - for( i = 0; i < 0x200; i++ ) fncode[i] = 0; - - i = 0; - while( (int)kdaca_fn[i][0] != -1 ){ - fncode[(int)kdaca_fn[i][0]] = kdaca_fn[i][1]; - i++; - } - - i = j = 0; - while( i < 0x200 ){ - if( fncode[i] != 0 ){ - if( i != j ){ - fn = (fncode[i] - fncode[j]) / (i - j); - for( k = 1; k < (i-j); k++ ) - fncode[k+j] = fncode[j] + fn*k; - j = i; - } - } - i++; - } -#if 0 - for( i = 0; i < 0x200; i++ ) - logerror("fncode[%04x] = %.2f\n", i, fncode[i] ); -#endif - -#else - int i; - for( i = 0; i < 0x200; i++ ) + for (int i = 0; i < 0x200; i++) { - //fncode[i] = (0x200 * 55) / (0x200 - i); - m_fncode[i] = (32 << BASE_SHIFT) / (0x200 - i); -// m_fncode[i] = ((0x200 * 55.2 / 880) / (0x200 - i)); - // = 512 * 55.2 / 220 / (512 - i) = 128 / (512 - i) - // logerror("2 : fncode[%04x] = %.2f\n", i, fncode[i] ); + m_fncode[i] = (32 << BASE_SHIFT) / (0x200 - i); } - -#endif } +uint32_t k007232_device::get_start_address(int channel) +{ + const uint32_t reg_index = (channel ? 6 : 0); + return (BIT(m_wreg[reg_index + 4], 0) << 16) | (m_wreg[reg_index + 3] << 8) | m_wreg[reg_index + 2] | m_bank[channel]; +} /************************************************/ /* Konami PCM write register */ /************************************************/ -WRITE8_MEMBER( k007232_device::write ) -{ - int r = offset; - int v = data; +WRITE8_MEMBER(k007232_device::write) +{ m_stream->update(); - m_wreg[r] = v; /* stock write data */ + m_wreg[offset] = data; // standard data write - if (r == 0x0c){ - /* external port, usually volume control */ - if (!m_port_write_handler.isnull()) m_port_write_handler(0, v, mem_mask); - return; - } - else if( r == 0x0d ){ - /* loopflag. */ - return; - } - else{ - int reg_port; - - reg_port = 0; - if (r >= 0x06){ - reg_port = 1; - r -= 0x06; + if (offset == 12) + { + // external port, usually volume control + m_port_write_handler(0, data); } - - switch (r){ - case 0x00: - case 0x01: + else if (offset == 13) { - /**** address step ****/ - int idx = (((((unsigned int)m_wreg[reg_port*0x06 + 0x01])<<8)&0x0100) | (((unsigned int)m_wreg[reg_port*0x06 + 0x00])&0x00ff)); -#if 0 - if( !reg_port && r == 1 ) - logerror("%04x\n" ,idx ); -#endif - - m_step[reg_port] = m_fncode[idx]; - break; + // loop flag, handled by standard data write } - case 0x02: - case 0x03: - case 0x04: - break; - case 0x05: - /**** start address ****/ - m_start[reg_port] = - ((((unsigned int)m_wreg[reg_port*0x06 + 0x04]<<16)&0x00010000) | - (((unsigned int)m_wreg[reg_port*0x06 + 0x03]<< 8)&0x0000ff00) | - (((unsigned int)m_wreg[reg_port*0x06 + 0x02] )&0x000000ff) | - m_bank[reg_port]); - if (m_start[reg_port] < m_pcmlimit ){ - m_play[reg_port] = 1; - m_addr[reg_port] = 0; + else + { + int channel = (offset >= 6 ? 1 : 0); + int reg_index = (offset >= 6 ? 6 : 0); + if (offset >= 6) + offset -= 6; + + switch (offset) + { + case 0: // address step, LSB + case 1: // address step, MSB + m_step[channel] = m_fncode[(BIT(m_wreg[reg_index + 1], 0) << 8) | m_wreg[reg_index]]; + if (machine().input().code_pressed(KEYCODE_K)) printf("Step: %02x, %02x = %04x (%08x)\n", m_wreg[reg_index + 1], m_wreg[reg_index], (BIT(m_wreg[reg_index + 1], 0) << 8) | m_wreg[reg_index], m_step[channel]); + break; + case 2: + case 3: + case 4: + // working data for start address + break; + case 5: // start address + m_start[channel] = get_start_address(channel); + if (machine().input().code_pressed(KEYCODE_K)) printf("Start: %08x\n", m_start[channel]); + if (m_start[channel] < m_pcmlimit) + { + m_play[channel] = 1; + m_addr[channel] = 0; + } + break; } - break; - } } } /************************************************/ /* Konami PCM read register */ /************************************************/ -READ8_MEMBER( k007232_device::read ) + +READ8_MEMBER(k007232_device::read) { - int r = offset; - int ch; - - if( r == 0x0005 || r == 0x000b ){ - ch = r/0x0006; - r = ch * 0x0006; - - m_start[ch] = - ((((unsigned int)m_wreg[r + 0x04]<<16)&0x00010000) | - (((unsigned int)m_wreg[r + 0x03]<< 8)&0x0000ff00) | - (((unsigned int)m_wreg[r + 0x02] )&0x000000ff) | - m_bank[ch]); - - if (m_start[ch] < m_pcmlimit ){ - m_play[ch] = 1; - m_addr[ch] = 0; - } + if (offset == 5 || offset == 11) + { + int channel = (offset == 11) ? 1 : 0; + + m_start[channel] = get_start_address(channel); + + if (m_start[channel] < m_pcmlimit) + { + m_play[channel] = 1; + m_addr[channel] = 0; + } } return 0; } /*****************************************************************************/ -void k007232_device::set_volume(int channel,int volumeA,int volumeB) +void k007232_device::set_volume(int channel, int vol_a, int vol_b) { - m_vol[channel][0] = volumeA; - m_vol[channel][1] = volumeB; + m_vol[channel][0] = vol_a; + m_vol[channel][1] = vol_b; } -void k007232_device::set_bank(int chABank, int chBBank ) +void k007232_device::set_bank(int chan_a_bank, int chan_b_bank) { - m_bank[0] = chABank<<17; - m_bank[1] = chBBank<<17; + m_bank[0] = chan_a_bank << 17; + m_bank[1] = chan_b_bank << 17; } /*****************************************************************************/ @@ -353,72 +189,81 @@ void k007232_device::set_bank(int chABank, int chBBank ) void k007232_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - int i; - - memset(outputs[0],0,samples * sizeof(*outputs[0])); - memset(outputs[1],0,samples * sizeof(*outputs[1])); + memset(outputs[0], 0, samples * sizeof(stream_sample_t)); + memset(outputs[1], 0, samples * sizeof(stream_sample_t)); - for( i = 0; i < KDAC_A_PCM_MAX; i++ ) + if (K007232_LOG_PCM) { - if (m_play[i]) - { - int volA,volB,j,out; - unsigned int addr, old_addr; - //int cen; - - /**** PCM setup ****/ - addr = m_start[i] + ((m_addr[i]>>BASE_SHIFT)&0x000fffff); - volA = m_vol[i][0] * 2; - volB = m_vol[i][1] * 2; -#if 0 - cen = (volA + volB) / 2; - volA = (volA + cen) < 0x1fe ? (volA + cen) : 0x1fe; - volB = (volB + cen) < 0x1fe ? (volB + cen) : 0x1fe; -#endif - - for( j = 0; j < samples; j++ ) - { - old_addr = addr; - addr = m_start[i] + ((m_addr[i]>>BASE_SHIFT)&0x000fffff); - while (old_addr <= addr) + for (int i = 0; i < KDAC_A_PCM_MAX; i++) { - if( (m_rom[old_addr] & 0x80) || old_addr >= m_pcmlimit ) - { - /* end of sample */ - - if( m_wreg[0x0d]&(1<<i) ) - { - /* loop to the beginning */ - m_start[i] = - ((((unsigned int)m_wreg[i*0x06 + 0x04]<<16)&0x00010000) | - (((unsigned int)m_wreg[i*0x06 + 0x03]<< 8)&0x0000ff00) | - (((unsigned int)m_wreg[i*0x06 + 0x02] )&0x000000ff) | - m_bank[i]); - addr = m_start[i]; - m_addr[i] = 0; - old_addr = addr; /* skip loop */ - } - else + if (m_play[i]) { - /* stop sample */ - m_play[i] = 0; + char filebuf[256]; + snprintf(filebuf, 256, "pcm%08x.wav", m_start[i]); + wav_file *file = wav_open(filebuf, stream.sample_rate(), 1); + if (file != nullptr) + { + uint32_t addr = m_start[i]; + while (!BIT(m_rom[addr], 7) && addr < m_pcmlimit) + { + int16_t out = ((m_rom[addr] & 0x7f) - 0x40) << 7; + wav_add_data_16(file, &out, 1); + addr++; + } + wav_close(file); + } } - break; - } - - old_addr++; } + } - if (m_play[i] == 0) - break; - - m_addr[i] += m_step[i]; - - out = (m_rom[addr] & 0x7f) - 0x40; + for (int i = 0; i < KDAC_A_PCM_MAX; i++) + { + if (m_play[i]) + { + /**** PCM setup ****/ + uint32_t addr_lsb = (m_addr[i] >> BASE_SHIFT) & 0x000fffff; + uint32_t addr = m_start[i] + addr_lsb; + int vol_a = m_vol[i][0] * 2; + int vol_b = m_vol[i][1] * 2; - outputs[0][j] += out * volA; - outputs[1][j] += out * volB; + for (int j = 0; j < samples; j++) + { + uint32_t old_addr = addr; + addr_lsb = (m_addr[i] >> BASE_SHIFT) & 0x000fffff; + addr = m_start[i] + addr_lsb; + while (old_addr <= addr) + { + if (BIT(m_rom[old_addr], 7) || old_addr >= m_pcmlimit) + { + // end of sample + if (BIT(m_wreg[13], i)) + { + /* loop to the beginning */ + m_start[i] = get_start_address(i); + addr = m_start[i]; + m_addr[i] = 0; + old_addr = addr; /* skip loop */ + } + else + { + /* stop sample */ + m_play[i] = 0; + } + break; + } + old_addr++; + } + + if (m_play[i] == 0) + break; + + m_addr[i] += m_step[i]; + + int out = (m_rom[addr] & 0x7f) - 0x40; + + outputs[0][j] += out * vol_a; + outputs[1][j] += out * vol_b; + } } } - } } diff --git a/src/devices/sound/k007232.h b/src/devices/sound/k007232.h index e8034b19a0c..84cabc1d6d9 100644 --- a/src/devices/sound/k007232.h +++ b/src/devices/sound/k007232.h @@ -38,9 +38,11 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; - void KDAC_A_make_fncode(); + void make_fncodes(); private: + uint32_t get_start_address(int channel); + static constexpr unsigned KDAC_A_PCM_MAX = 2; /* Channels per chip */ // internal state @@ -51,15 +53,15 @@ private: uint32_t m_start[KDAC_A_PCM_MAX]; uint32_t m_step[KDAC_A_PCM_MAX]; uint32_t m_bank[KDAC_A_PCM_MAX]; - int m_play[KDAC_A_PCM_MAX]; + int m_play[KDAC_A_PCM_MAX]; uint8_t m_wreg[0x10]; /* write data */ uint32_t m_pcmlimit; - sound_stream * m_stream; + sound_stream * m_stream; uint32_t m_fncode[0x200]; - devcb_write8 m_port_write_handler; + devcb_write8 m_port_write_handler; }; DECLARE_DEVICE_TYPE(K007232, k007232_device) |