Skip to content

Instantly share code, notes, and snippets.

@superctr
Last active May 31, 2020 14:09
Show Gist options
  • Save superctr/fa2491fcf48b070459db30814eb7330f to your computer and use it in GitHub Desktop.
Save superctr/fa2491fcf48b070459db30814eb7330f to your computer and use it in GitHub Desktop.
qsound register description

CPS2 QSound DSP Register Description

Channel Registers (00-7F)

Bank (x0, x8)

This sets the upper 8 bits of the sample address (bit 16-23). The most significant bit (bit 15) must be set to 1. Keep in mind the bank number is not affected by the sample address.

Note:

The bank register address is aligned so that the first register 0x00 affects channel 15, 0x08 channel 0, and so on.

Address (x1, x9)

This sets the sample address.

Note:

Always set this register when starting sample playback, as this register is also used to track the current position of the sample.

Rate (x2, xA)

This sets the sample frequency. Bit 12-15 corresponds directly to the sample address (so if bit 12 is set to 1 and all other bits to 0, the sample position is advanced by one byte every tick). Sample rate is calculated in Hertz as follows:

Fs=n/1024×24038

Phase (x3, xB)

This register contains the lower 16-bits fractional part of the sample address. Set this register to 0x8000 when starting a sample. Otherwise do not write to this register.

Loop (x4, xC)

This sets the length of the sample loop. When the sample counter reaches the end position, the contents of the loop register is subtracted from the sample address.

End (x5, xD)

This sets the end position of the sample.

Volume (x6, xE)

This sets the sample volume. The recommended range is 0x0000-0x1FFF, a greater value may cause clipping. The phase can be inverted by setting the volume to a negative value (0xE000-0xFFFF).

Panning (80-8F)

This sets the panpot. Use values -16 to 16, then add 0x120 for the Q1 stereo function, or 0x150 for a “linear” stereo function (with no Q1 effect).

Echo (BA-C9)

This sets the channel-specific volume of the echo (reverb). The echo volume is applied after the channel volume, so the range can be 0x0000-0x7FFF. As with the channel volume, a negative value inverts the phase of the echo. Notice that the echo effect inverts phase on one of the speakers anyway.

ADPCM registers

Address (CA, CE, D2)

This sets the start position of the ADPCM sample.

End (CB, CF, D3)

Bank (CC, D0, D4)

This sets the upper bits of the sample address (bit 16-23).

Volume (CD, D1, D5)

This sets the sample volume. The recommended range is 0x0000-0x1FFF, a greater value may cause clipping. The phase can be inverted by setting the volume to a negative value (0xE000-0xFFFF). This is not updated until a key on is triggered.

Key On (D6-D8)

Write a non-zero value to a start ADPCM playback. The sample rate of ADPCM samples is fixed at 8012 Hz. To stop ADPCM playback, set the Volume to 0 and perform a Key-On.

Panning (90-92)

This sets the panpot. Use values -16 to 16, then add 0x120 for the Q1 stereo function, or 0x150 for a “linear” stereo function (with no Q1 effect).

ADPCM playback is muted by writing ‘0’ to this register. As this register controls the playback volume of the ADPCM sample, writing a non-zero value will cause noise to be played if the channel has already been muted.

Global registers

Echo Feedback (93)

This sets the volume of the echo feedback; the data that is fed back when reading from the echo buffer. Recommended range is 0x0000-0x1FFF (16383), a negative value will cause the echo feedback to be phase inverted.

Echo Delay (D9)

This sets the length of the echo buffer. Valid range is 0x055A-0x0FFF for stereo filter mode, and 0x0542-0x0FFF for quad filter mode. Setting this register outside this range may cause malfunction.

Q1 Component Filter Select (DA-DD)

Register Filter mode
0xda Wet (left)
0xdb Dry (left)
0xdc Wet (right)
0xdd Dry (right)

In the stereo filter mode, only the “Wet” filters are active. In quad filter mode, both “Wet” and “Dry” filters are active. Write the “Value” in the below table to each register to select the desired filter.

Filter no. Valid filter mode Description Value
0 Stereo filter 0x0D53
1 Stereo filter Default for left speaker 0x0DB2
2 Stereo filter Default for right speaker 0x0E11
3 Stereo filter 0x0E70
4 Stereo filter 0x0ECF
5 Any No output 0x0F2E
6 Quad filter Default for left speaker 0x0F73
7 Stereo filter No filtering 0x0FA0
8 Quad filter No filtering; Default for right speaker 0x0FA4

After changing the filter, the “Refresh Filter” flag for the appropriate mode should be written to the Q1 Component Mode / Reset Flag register (E3).

Q1 Component Delay (DE-E1)

This sets the delay of each Q1 component. Normally, the dry component is delayed to compensate for the delays caused by the FIR filter of the wet component. The length of the delay is usually 45 samples for stereo filter mode. To apply the delay, write a non-zero value to the Q1 Component Delay Recalculation Flag register (E2)

Q1 Component Delay Recalculation Flag (E2)

Q1 Component Mode / Reset Flag (E3)

Mode table

Normally, only the "Stereo filter" mode is used. Quad filter mode was never used by Capcom and not completely tested.

Current filter mode Target filter mode Description Value
Any Stereo filter Soft reset 0x0000
Any Stereo filter Reset chip 0x0288
Stereo filter Stereo filter Refresh filter 0x0039
Any Quad filter Reset chip 0x061A
Quad filter Quad filter Refresh filter 0x004F
Any None Test (Low frequency) Not emulated by HLE 0x000C
Any None Test (High frequency) Not emulated by HLE 0x000F
Soft Reset

Resets everything and sets the filter mode to the stereo filter.

Reset chip

All registers are reset to the default values and the filter mode is set to the specified mode before proceeding normal operation.

Refresh filter

New filter parameters are retrieved from the DSP ROM before proceeding normal operation.

Test

The test routine outputs a sawtooth wave. All other functions of the DSP are disabled in this state. To exit the test routine, write 0x0000 to the Q1 Component Mode / Reset Flag (F3) to reset the chip.

Q1 Component Volume (E4-E7)

This sets the volume of each Q1 component. The default value is 16383 (0x3FFF). The phase can be inverted by writing a negative value.

Sample data

Sample ROM bank layout

The table below illustrates how banks are laid out by the Q1 DSP. “Upper” refers to a positive sample address, while “Lower” refers to a negative sample address. A sample starting in the “Lower” area may continue into the “Upper” area of the same bank. However, samples starting in the “Upper” area may not continue into the “Lower” area or into any other bank.

Physical 0x000000 0x08000 0x10000 0x18000 0x20000 0xFF0000 0xFF8000
Bank 0x8000 0x8000 0x8001 0x8001 0x8002 0x80FF 0x80FF
Part Upper Lower Upper Lower Upper Upper Lower

Constraints

A complete sample must fit entirely within one bank. The sample counter is a signed value internally, and it is clamped to prevent overflow/underflow. Therefore the sample cannot cross the boundary at 0x8000, preventing samples longer than 32K if 0 is assumed as the start position. To play longer samples up to 64K, it is possible to set the start address to a “negative” value (0x8000-0xFFFF) and the end position to a “positive” value (0x0000-0x7FFF). The sample also needs to be stored in ROM as such.

ADPCM Format

ADPCM sample playback is limited at 8 KHz. It might be a good idea to amplify higher frequencies or apply a high-pass filter, as the upper band frequencies are typically attenuated after encoding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment