Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add improved qsound_hle core #3819

Merged
merged 4 commits into from Aug 18, 2018
Merged

Conversation

Lord-Nightmare
Copy link
Contributor

This adds the rewritten QSound HLE by ValleyBell and superctr with full spatialization, among other accuracy improvements

qsound_hle: use enums for most DSP ROM addresses, move them to qsoundhle.h
@superctr
Copy link
Contributor

superctr commented Aug 3, 2018

This commit addresses the issues brought up in the previous thread #3821.

@Tafoid
Copy link
Contributor

Tafoid commented Aug 8, 2018

I've done a great deal of testing of this PR today. First off, it compiles cleaning with current GIT as of this writing. I've manually ran about a dozen machines with binaries from before and after to listen for changes and while I didn't notice anything standing out good or bad. Also in my regression testing of all 33 (before vs after) there was no breaks in audio output as far as I could determine. I did my testing on the 4 drivers affected (cps1, cps2, zn, vgmplay) and all of them, outside of needed wavdata changes deal with the new registers and commands being processed, worked and sounded fine. The changes appear to be consistent across the board where machines with the same datahash also shared the same datahash after this was applied. The only issue I had was that I needed to make a "qsound_hle" file (duplicate data/dump) from the existing "qsound" because it appears the HLE uses the rom as well as the LLE.. reading data from it to construct data tables. Since there isn't a way for both implementations to share the same "qsound" device, this appears to be valid.

@balr0g
Copy link
Contributor

balr0g commented Aug 13, 2018

Are there any remaining issues with this PR that would keep it from being merged?

@balr0g
Copy link
Contributor

balr0g commented Aug 14, 2018

[23:34:14] the type punning has to go
[23:34:51] and the formatting has to at least be cleaned up

Copy link
Member

@cuavas cuavas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code still needs a lot of cleanup.

}

} // anonymous namespace
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use macros when constexpr functions are better (multiple evaluation of expressions, etc.). Also, this can be defined in terms of std::min and std::max.

memset(m_channel, 0, sizeof(m_channel));
// state save
// PCM registers
for(int j=0;j<16;j++) // PCM voices
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the convention used in existing files - space between control keyword and opening parenthesis of control expression, and spaces after semicolon/comma separators.

int m_state_counter;
int m_ready_flag;

uint16_t *register_map[256];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this approach rather than a flat array of uint16_t for the registers with accessors for the common access patterns?


uint16_t *register_map[256];

inline uint16_t read_dsp_rom(uint16_t addr) { return m_dsp_rom[addr&0xfff]; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline qualifier has no effect here and adds clutter - if the body is present at declaration inline is implied.

int rvol; // right volume
} m_channel[16];
// sub functions
inline int16_t get_sample(uint16_t bank,uint16_t address);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline qualifier without body present at declaration generally doesn't produce desired effect. If you want to suppress export of the body, you should put the inline qualifier on the definition.

}

// Update the delay read position to match new delay length
void qsound_hle_device::delay_update(struct qsound_delay *d)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things that operate entirely on an inner structure/class like this should be members of the inner structure/class, otherwise you're passing a useless this pointer for the outer class and need an explicit parameter for the inner structure/class.

qsound_adpcm temp2 = {}; std::fill(std::begin(m_adpcm),std::end(m_adpcm),temp2);
qsound_fir temp3 = {}; std::fill(std::begin(m_filter),std::end(m_filter),temp3);
std::fill(std::begin(m_alt_filter),std::end(m_alt_filter),temp3);
qsound_delay temp4 = {}; std::fill(std::begin(m_wet),std::end(m_wet),temp4);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You really need to provide member initialisation for the qsound_voice etc. structures for this to work properly, and you don't need the locals, as you can construct a temporary in the call, e.g. std::fill(std::begin(m_voice), std::end(m_voice), qsound_voice());

int16_t qsound_hle_device::get_sample(uint16_t bank,uint16_t address)
{
uint32_t rom_addr;
uint8_t sample_data;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cases like this, please declare variables at initialisation and use const where appropriate to reduce mutable state.

{
// unused registers
for(int i=0;i<256;i++)
register_map[i] = NULL;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use nullptr as a null pointer constant. Also, probably a case for std::fill

m_ready_flag = 0;
m_out[0] = m_out[1] = 0;
m_state = 0;
m_state_counter = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resetting the device would cause the DSP to jump to address zero, causing it to zero its registers and reinitialise.

@rb6502
Copy link
Contributor

rb6502 commented Aug 18, 2018

Sorry about the bit of drama, this will still get a fair review once Vas's notes have been dealt with. As-is the translation from the original DSP assembly is a little too literal, or what we used to call 'Achocode'. With the changes addressed that should be much less of a problem.

@rb6502 rb6502 merged commit e6d8313 into mamedev:master Aug 18, 2018
@superctr superctr deleted the qsound_hle_mame200 branch August 20, 2018 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants