diff options
author | ajrhacker <ajrhacker@users.noreply.github.com> | 2020-03-02 09:20:13 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-02 09:20:13 -0500 |
commit | 527cb1d5284b368752cbdfd42e647d15bb833b89 (patch) | |
tree | 986b16c27fde84f4e9c9540511d9d1b8a0017009 /src/devices | |
parent | 0a6807102b1a6512d66748f034256bd24bcae1a4 (diff) | |
parent | 553d2b74df5ddb2621dd18e6ef172bfe51b3f2a3 (diff) |
Merge pull request #6364 from cam900/x1_010_freq
x1_010.cpp : Accurate frequency calculation, Minor cleanups
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/sound/x1_010.cpp | 156 | ||||
-rw-r--r-- | src/devices/sound/x1_010.h | 12 |
2 files changed, 84 insertions, 84 deletions
diff --git a/src/devices/sound/x1_010.cpp b/src/devices/sound/x1_010.cpp index f6847a2df08..a52f8504ddd 100644 --- a/src/devices/sound/x1_010.cpp +++ b/src/devices/sound/x1_010.cpp @@ -31,21 +31,22 @@ Registers: ---- 3210 PCM Volume 2 (R?) Waveform No. - 2 PCM Frequency - Waveform Pitch Lo + 2 PCM Frequency (4.4 fixed point) + Waveform Pitch Lo (6.10 fixed point) - 3 Waveform Pitch Hi + 3 Waveform Pitch Hi (6.10 fixed point) 4 PCM Sample Start / 0x1000 [Start/End in bytes] - Waveform Envelope Time + Waveform Envelope Time (.10 fixed point) 5 PCM Sample End 0x100 - (Sample End / 0x1000) [PCM ROM is Max 1MB?] Waveform Envelope No. 6 Reserved 7 Reserved - offset 0x0000 - 0x0fff Wave form data - offset 0x1000 - 0x1fff Envelope data + offset 0x0000 - 0x007f Channel data + offset 0x0080 - 0x0fff Envelope data + offset 0x1000 - 0x1fff Wave form data *1 : when 0 is specified, hardware interrupt is caused (always return soon) @@ -66,12 +67,11 @@ Registers: namespace { -#define FREQ_BASE_BITS 8 // Frequency fixed decimal shift bits -#define ENV_BASE_BITS 16 // wave form envelope fixed decimal shift bits #define VOL_BASE (2*32*256/30) // Volume base /* this structure defines the parameters for a channel */ -struct X1_010_CHANNEL { +struct X1_010_CHANNEL +{ unsigned char status; unsigned char volume; // volume / wave form no. unsigned char frequency; // frequency / pitch lo @@ -86,7 +86,7 @@ struct X1_010_CHANNEL { DEFINE_DEVICE_TYPE(X1_010, x1_010_device, "x1_010", "Seta X1-010") -x1_010_device::x1_010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +x1_010_device::x1_010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, X1_010, tag, owner, clock) , device_sound_interface(mconfig, *this) , device_rom_interface(mconfig, *this, 20) @@ -107,23 +107,22 @@ x1_010_device::x1_010_device(const machine_config &mconfig, const char *tag, dev void x1_010_device::device_start() { - int i; - m_base_clock = clock(); m_rate = clock() / 512; - for( i = 0; i < NUM_CHANNELS; i++ ) { + for (int i = 0; i < NUM_CHANNELS; i++) + { m_smp_offset[i] = 0; m_env_offset[i] = 0; } /* Print some more debug info */ - LOG_SOUND("masterclock = %d rate = %d\n", clock(), m_rate ); + LOG_SOUND("masterclock = %d rate = %d\n", clock(), m_rate); /* get stream channels */ m_stream = machine().sound().stream_alloc(*this, 0, 2, m_rate); - m_reg = make_unique_clear<uint8_t[]>(0x2000); - m_HI_WORD_BUF = make_unique_clear<uint8_t[]>(0x2000); + m_reg = make_unique_clear<u8[]>(0x2000); + m_HI_WORD_BUF = make_unique_clear<u8[]>(0x2000); save_item(NAME(m_rate)); save_item(NAME(m_sound_enable)); @@ -171,13 +170,12 @@ u8 x1_010_device::read(offs_t offset) void x1_010_device::write(offs_t offset, u8 data) { - int channel, reg; - - channel = offset/sizeof(X1_010_CHANNEL); - reg = offset%sizeof(X1_010_CHANNEL); + int channel = offset/sizeof(X1_010_CHANNEL); + int reg = offset%sizeof(X1_010_CHANNEL); - if( channel < NUM_CHANNELS && reg == 0 - && (m_reg[offset]&1) == 0 && (data&1) != 0 ) { + if (channel < NUM_CHANNELS && reg == 0 + && (m_reg[offset] & 1) == 0 && (data & 1) != 0) + { m_smp_offset[channel] = 0; m_env_offset[channel] = 0; } @@ -190,18 +188,17 @@ void x1_010_device::write(offs_t offset, u8 data) u16 x1_010_device::word_r(offs_t offset) { - uint16_t ret; - - ret = m_HI_WORD_BUF[offset]<<8; - ret += (read( offset )&0xff); + u16 ret; + ret = m_HI_WORD_BUF[offset] << 8; + ret |= (read(offset) & 0xff); LOG_REGISTER_READ("%s: Read X1-010 Offset:%04X Data:%04X\n", machine().describe_context(), offset, ret); return ret; } void x1_010_device::word_w(offs_t offset, u16 data) { - m_HI_WORD_BUF[offset] = (data>>8)&0xff; - write( offset, data&0xff ); + m_HI_WORD_BUF[offset] = (data >> 8) & 0xff; + write(offset, data & 0xff); LOG_REGISTER_WRITE("%s: Write X1-010 Offset:%04X Data:%04X\n", machine().describe_context(), offset, data); } @@ -212,81 +209,84 @@ void x1_010_device::word_w(offs_t offset, u16 data) void x1_010_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - X1_010_CHANNEL *reg; - int ch, i, volL, volR, freq, div; - int8_t data; - uint8_t *env; - uint32_t start, end, smp_offs, smp_step, env_offs, env_step, delta; - // mixer buffer zero clear - memset( outputs[0], 0, samples*sizeof(*outputs[0]) ); - memset( outputs[1], 0, samples*sizeof(*outputs[1]) ); + memset(outputs[0], 0, samples*sizeof(*outputs[0])); + memset(outputs[1], 0, samples*sizeof(*outputs[1])); -// if( m_sound_enable == 0 ) return; +// if (m_sound_enable == 0) return; - for( ch = 0; ch < NUM_CHANNELS; ch++ ) { - reg = (X1_010_CHANNEL *)&(m_reg[ch*sizeof(X1_010_CHANNEL)]); - if( (reg->status&1) != 0 ) { // Key On + for (int ch = 0; ch < NUM_CHANNELS; ch++) + { + X1_010_CHANNEL *reg = (X1_010_CHANNEL *)&(m_reg[ch*sizeof(X1_010_CHANNEL)]); + if ((reg->status & 1) != 0) // Key On + { stream_sample_t *bufL = outputs[0]; stream_sample_t *bufR = outputs[1]; - div = (reg->status&0x80) ? 1 : 0; - if( (reg->status&2) == 0 ) { // PCM sampling - start = reg->start*0x1000; - end = (0x100-reg->end)*0x1000; - volL = ((reg->volume>>4)&0xf)*VOL_BASE; - volR = ((reg->volume>>0)&0xf)*VOL_BASE; - smp_offs = m_smp_offset[ch]; - freq = reg->frequency>>div; + const int div = (reg->status & 0x80) ? 1 : 0; + if ((reg->status & 2) == 0) // PCM sampling + { + const u32 start = reg->start << 12; + const u32 end = (0x100 - reg->end) << 12; + const int volL = ((reg->volume >> 4) & 0xf) * VOL_BASE; + const int volR = ((reg->volume >> 0) & 0xf) * VOL_BASE; + u32 smp_offs = m_smp_offset[ch]; + int freq = reg->frequency >> div; // Meta Fox does write the frequency register, but this is a hack to make it "work" with the current setup // This is broken for Arbalester (it writes 8), but that'll be fixed later. - if( freq == 0 ) freq = 4; - smp_step = (uint32_t)((float)m_base_clock/8192.0f - *freq*(1<<FREQ_BASE_BITS)/(float)m_rate); - if( smp_offs == 0 ) { + if (freq == 0) freq = 4; + const u32 smp_step = freq; + if (smp_offs == 0) + { LOG_SOUND("Play sample %p - %p, channel %X volume %d:%d freq %X step %X offset %X\n", start, end, ch, volL, volR, freq, smp_step, smp_offs); } - for( i = 0; i < samples; i++ ) { - delta = smp_offs>>FREQ_BASE_BITS; + for (int i = 0; i < samples; i++) + { + const u32 delta = smp_offs >> 4; // sample ended? - if( start+delta >= end ) { + if (start+delta >= end) + { reg->status &= 0xfe; // Key off break; } - data = (int8_t)(read_byte(start+delta)); - *bufL++ += (data*volL/256); - *bufR++ += (data*volR/256); + const s8 data = (s8)(read_byte(start+delta)); + *bufL++ += (data * volL / 256); + *bufR++ += (data * volR / 256); smp_offs += smp_step; } m_smp_offset[ch] = smp_offs; - } else { // Wave form - start = (reg->volume*128+0x1000); - smp_offs = m_smp_offset[ch]; - freq = ((reg->pitch_hi<<8)+reg->frequency)>>div; - smp_step = (uint32_t)((float)m_base_clock/128.0f/1024.0f/4.0f*freq*(1<<FREQ_BASE_BITS)/(float)m_rate); - - env = (uint8_t *)&(m_reg[reg->end*128]); - env_offs = m_env_offset[ch]; - env_step = (uint32_t)((float)m_base_clock/128.0f/1024.0f/4.0f*reg->start*(1<<ENV_BASE_BITS)/(float)m_rate); + } + else // Wave form + { + const u16 start = ((reg->volume << 7) + 0x1000); + u32 smp_offs = m_smp_offset[ch]; + const int freq = ((reg->pitch_hi<<8)+reg->frequency) >> div; + const u32 smp_step = freq; + + const u16 env = reg->end << 7; + u32 env_offs = m_env_offset[ch]; + const u32 env_step = reg->start; /* Print some more debug info */ - if( smp_offs == 0 ) { + if (smp_offs == 0) + { LOG_SOUND("Play waveform %X, channel %X volume %X freq %4X step %X offset %X\n", reg->volume, ch, reg->end, freq, smp_step, smp_offs); } - for( i = 0; i < samples; i++ ) { - int vol; - delta = env_offs>>ENV_BASE_BITS; + for (int i = 0; i < samples; i++) + { + const u32 delta = env_offs >> 10; // Envelope one shot mode - if( (reg->status&4) != 0 && delta >= 0x80 ) { + if ((reg->status & 4) != 0 && delta >= 0x80) + { reg->status &= 0xfe; // Key off break; } - vol = *(env+(delta&0x7f)); - volL = ((vol>>4)&0xf)*VOL_BASE; - volR = ((vol>>0)&0xf)*VOL_BASE; - data = (int8_t)(m_reg[start+((smp_offs>>FREQ_BASE_BITS)&0x7f)]); - *bufL++ += (data*volL/256); - *bufR++ += (data*volR/256); + const u8 vol = m_reg[env + (delta & 0x7f)]; + const int volL = ((vol >> 4) & 0xf) * VOL_BASE; + const int volR = ((vol >> 0) & 0xf) * VOL_BASE; + const s8 data = (s8)(m_reg[start + ((smp_offs >> 10) & 0x7f)]); + *bufL++ += (data * volL / 256); + *bufR++ += (data * volR / 256); smp_offs += smp_step; env_offs += env_step; } diff --git a/src/devices/sound/x1_010.h b/src/devices/sound/x1_010.h index fc616e99cfd..5f85fe77671 100644 --- a/src/devices/sound/x1_010.h +++ b/src/devices/sound/x1_010.h @@ -8,7 +8,7 @@ class x1_010_device : public device_t, public device_sound_interface, public device_rom_interface { public: - x1_010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + x1_010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); u8 read(offs_t offset); void write(offs_t offset, u8 data); @@ -38,12 +38,12 @@ private: int m_rate; // Output sampling rate (Hz) sound_stream * m_stream; // Stream handle int m_sound_enable; // sound output enable/disable - std::unique_ptr<uint8_t[]> m_reg; // X1-010 Register & wave form area - std::unique_ptr<uint8_t[]> m_HI_WORD_BUF; // X1-010 16bit access ram check avoidance work - uint32_t m_smp_offset[NUM_CHANNELS]; - uint32_t m_env_offset[NUM_CHANNELS]; + std::unique_ptr<u8[]> m_reg; // X1-010 Register & wave form area + std::unique_ptr<u8[]> m_HI_WORD_BUF; // X1-010 16bit access ram check avoidance work + u32 m_smp_offset[NUM_CHANNELS]; + u32 m_env_offset[NUM_CHANNELS]; - uint32_t m_base_clock; + u32 m_base_clock; }; DECLARE_DEVICE_TYPE(X1_010, x1_010_device) |