diff --git a/src/devices/sound/swp00.cpp b/src/devices/sound/swp00.cpp index d2a3818f36e..2aabf9f06fc 100644 --- a/src/devices/sound/swp00.cpp +++ b/src/devices/sound/swp00.cpp @@ -321,7 +321,6 @@ void swp00_device::device_start() save_item(NAME(m_lfo_phase)); save_item(NAME(m_sample_pos)); - save_item(NAME(m_sample_increment)); save_item(NAME(m_envelope_level)); save_item(NAME(m_glo_level_cur)); @@ -340,6 +339,10 @@ void swp00_device::device_start() save_item(NAME(m_decay_done)); save_item(NAME(m_lpf_done)); + save_item(NAME(m_dpcm_current)); + save_item(NAME(m_dpcm_next)); + save_item(NAME(m_dpcm_address)); + for(int i=0; i != 128; i++) { u32 v = 0; switch(i >> 3) { @@ -353,24 +356,12 @@ void swp00_device::device_start() m_global_step[i] = v; } - // Log to linear 8-bits sample decompression. Statistics say - // that's what it should look like. Note that 0 can be encoded - // both as 0x00 and 0x80, and as it happens 0x80 is never used in - // these samples. Ends up with a 55dB dynamic range, to compare - // with 8bits 48dB, 12bits 72dB and 16bits 96dB. + // Delta-packed samples decompression. - // Rescale so that it's roughly 16 bits. Range ends up being +/- 78c0. - - for(int i=0; i<32; i++) { - m_sample_log8[ i] = i << 0; - m_sample_log8[0x20|i] = (i << 1) + 0x21; - m_sample_log8[0x40|i] = (i << 2) + 0x62; - m_sample_log8[0x60|i] = (i << 3) + 0xe3; - } for(int i=0; i<128; i++) { - s16 base = m_sample_log8[i] << 6; - m_sample_log8[i | 0x80] = - base; - m_sample_log8[i] = + base; + s16 base = ((i & 0x1f) << (7+(i >> 5))) + (((1 << (i >> 5))-1) << 12); + m_dpcm[i | 0x80] = - base; + m_dpcm[i] = + base; } } @@ -465,7 +456,6 @@ void swp00_device::device_reset() std::fill(m_lfo_phase.begin(), m_lfo_phase.end(), 0); std::fill(m_sample_pos.begin(), m_sample_pos.end(), 0); - std::fill(m_sample_increment.begin(), m_sample_increment.end(), 0); std::fill(m_envelope_level.begin(), m_envelope_level.end(), 0); std::fill(m_glo_level_cur.begin(), m_glo_level_cur.end(), 0); @@ -483,6 +473,10 @@ void swp00_device::device_reset() std::fill(m_decay.begin(), m_decay.end(), false); std::fill(m_decay_done.begin(), m_decay_done.end(), false); std::fill(m_lpf_done.begin(), m_lpf_done.end(), false); + + std::fill(m_dpcm_current.begin(), m_dpcm_current.end(), false); + std::fill(m_dpcm_next.begin(), m_dpcm_next.end(), false); + std::fill(m_dpcm_address.begin(), m_dpcm_address.end(), false); } void swp00_device::rom_bank_pre_change() @@ -914,6 +908,10 @@ void swp00_device::keyon(int chan) m_decay[chan] = false; m_decay_done[chan] = false; + m_dpcm_current[chan] = 0; + m_dpcm_next[chan] = 0; + m_dpcm_address[chan] = m_sample_address[chan] - m_sample_start[chan]; + m_lpf_value[chan] = m_lpf_target_value[chan]; m_lpf_timer[chan] = 0x4000000; m_lpf_ha[chan] = 0; @@ -1278,21 +1276,21 @@ void swp00_device::sound_stream_update(sound_stream &stream, std::vector> 2)*6; switch(spos & 3) { - case 0: { // .abc .... .... + case 0: { // Cabc ..AB .... .... u16 w0 = read_word(adr); u16 w1 = read_word(adr+2); val0 = (w0 & 0x0fff) << 4; val1 = ((w0 & 0xf000) >> 8) | ((w1 & 0x00ff) << 8); break; } - case 1: { // C... ..AB .... + case 1: { // c... BCab ...A .... u16 w0 = read_word(adr); u16 w1 = read_word(adr+2); u16 w2 = read_word(adr+4); @@ -1300,14 +1298,14 @@ void swp00_device::sound_stream_update(sound_stream &stream, std::vector> 4) | ((w2 & 0x000f) << 12); break; } - case 2: { // .... bc.. ...a + case 2: { // .... bc.. ABCa .... u16 w1 = read_word(adr+2); u16 w2 = read_word(adr+4); val0 = ((w1 & 0xff00) >> 4) | ((w2 & 0x000f) << 12); val1 = w2 & 0xfff0; break; } - case 3: { // .... .... ABC. + case 3: { // .... .... abc. .ABC u16 w2 = read_word(adr+4); u16 w3 = read_word(adr+6); val0 = w2 & 0xfff0; @@ -1323,11 +1321,23 @@ void swp00_device::sound_stream_update(sound_stream &stream, std::vector 0x7fff) + sample = 0x7fff; + m_dpcm_next[chan] = sample; + } + val0 = m_dpcm_current[chan]; + val1 = m_dpcm_next[chan]; break; } + } s32 mul = m_sample_pos[chan] & 0x7fff; s32 sample = (val1 * mul + val0 * (0x8000 - mul)) >> 7; @@ -1363,9 +1373,11 @@ void swp00_device::sound_stream_update(sound_stream &stream, std::vector> 15) >= m_sample_end[chan]); + m_dpcm_address[chan] += (m_sample_pos[chan] >> 15) - (prev >> 15); } } diff --git a/src/devices/sound/swp00.h b/src/devices/sound/swp00.h index 36dfba1677d..21b7b384085 100644 --- a/src/devices/sound/swp00.h +++ b/src/devices/sound/swp00.h @@ -43,7 +43,7 @@ private: static const std::array decay_linear_step; static const std::array panmap; std::array m_global_step; - std::array m_sample_log8; + std::array m_dpcm; static const std::array lfo_shape_centered_saw; static const std::array lfo_shape_centered_tri; @@ -83,7 +83,6 @@ private: std::array m_lfo_phase; std::array m_sample_pos; - std::array m_sample_increment; std::array m_envelope_level; std::array m_glo_level_cur; std::array m_pan_l; @@ -95,6 +94,9 @@ private: std::array m_lpf_ha; std::array m_lpf_hb; std::array m_active, m_decay, m_decay_done, m_lpf_done; + std::array m_dpcm_current; + std::array m_dpcm_next; + std::array m_dpcm_address; u16 m_waverom_val; u8 m_waverom_access;