ADPCM: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
(Created page with "'''A'''daptive '''D'''ifferential '''P'''ulse '''C'''ode '''M'''odulation is a lossy audio compression algorithm. It is essentially PCM with dynamic quantizing step adaptation...")
 
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''A'''daptive '''D'''ifferential '''P'''ulse '''C'''ode '''M'''odulation is a lossy audio compression algorithm. It is essentially PCM with dynamic quantizing step adaptation. See [[https://en.wikipedia.org/wiki/Adaptive_differential_pulse-code_modulation Wikipedia article]] for more general informations.
'''A'''daptive '''D'''ifferential '''P'''ulse '''C'''ode '''M'''odulation is a lossy audio compression algorithm. It is essentially PCM with dynamic quantizing step adaptation. See [[https://en.wikipedia.org/wiki/Adaptive_differential_pulse-code_modulation Wikipedia article]] for more general informations.


The NeoGeo's {{Chipname|YM2610}} uses this format for samples stored in the [[V ROM]]s. Each sample is coded in 4 bits and approximately reconstituted as 12 bits during playback.
The NeoGeo's {{Chipname|YM2610}} uses this format for samples stored in the [[V ROM]]s or [[PCM file]]s. Each sample is coded in 4 bits and approximately reconstituted as 12 or 16 bits during playback.


Note that the Yamaha ADPCM format is different from the common IMA and Microsoft ADPCM formats. See [[ADPCM codecs]] for encoding and decoding tools.
Note that the Yamaha ADPCM format is different from the common IMA and Microsoft ADPCM formats. See [[ADPCM codecs]] for encoding and decoding tools.
The NeoGeo CD can't use ADPCM-B.
=Status register=
{| class="regdef"
|'''Address (Z80 port 4)'''
|'''Data (Z80 port 5)'''
|Value on [[reset]]
|-
|$1C
|{{8BitRegister|B|1|-|1|A6|1|A5|1|A4|1|A3|1|A2|1|A1|1|}}
|$00
|}
Each bit corresponds to an ADPCM channel.
* Write 1 to reset and mask selected flag
* Write 0 to unmask selected flag
Masking a flag will prevent it from being raised when a channel reaches its end address. This means it is required to write 1 to clear the flag, then 0 to keep it active.
Flags must be manually cleared, playing a new sample on the channel won't clear it and the channel will stay silent.
=ADPCM-A=
The ADPCM-A part has '''6 channels''' with a '''fixed''' playback frequency of: 8MHz ({{Sig|8M|8M}}) / 12 (prescaler) / 6 clocks per access / 6 channels = ~'''18.5185kHz'''.
Audio is compressed as 4bit per sample and played back as '''12bit'''.
==Registers==
{| class="regdef"
|'''Address (Z80 port 6)'''
|'''Data (Z80 port 7)'''
|Value on [[reset]]
|
|-
|$00
|{{8BitRegister|Dump|1|-|1|CH6|1|CH5|1|CH4|1|CH3|1|CH2|1|CH1|1}}
|$00
|'Dump' is the key on/off bit. Write 0 to start playing specified channels and 1 to stop playing.
|-
|$01
|{{8BitRegister|-|2|Master volume|6}}
|$00
|Actually an attenuator, $3F is the loudest.
|-
|$02
|{{8BitRegister|?|8}}
|$00 ?
|Test register. Ignore or set to $00 for normal operation.
|-
|$08~$0D (one for each channel)
|{{8BitRegister|L|1|R|1|-|1|Channel volume|5}}
|$00
|Actually an attenuator, $1F is the loudest. L/R routes the output to the left and/or right channels.
|-
|$10~$15 (one for each channel)
|{{8BitRegister|Sample's start address/256 LSB|8}}
|$00
|rowspan="4"|All ADPCM addresses must match a 256-byte boundary (bits 0~7 = 0).
Example: if register $18 = $1D and register $10 = $23, the sample's start address will be $1D2300.
|-
|$18~$1D (one for each channel)
|{{8BitRegister|Sample's start address/256 MSB|8}}
|$00
|-
|$20~$25 (one for each channel)
|{{8BitRegister|Sample's stop address/256 LSB|8}}
|$00
|-
|$28~$2D (one for each channel)
|{{8BitRegister|Sample's stop address/256 MSB|8}}
|$00
|}
=ADPCM-B=
The ADPCM-B part only has '''1 channel''', but the playback frequency can be set from '''1.85kHz''' to: 8MHz ({{Sig|8M|8M}}) / 2 / 12 (prescaler) / 6 clocks per access = ~'''55.555kHz'''.
Audio is compressed as 4bit per sample and played back as '''16bit'''.
==Registers==
See [[ADPCM]] for details on this part's operation.
{| class="regdef"
|'''Address (Z80 port 4)'''
|'''Data (Z80 port 5)'''
|Value on [[reset]]
|
|-
|$10
|{{8BitRegister|Start|1|-|2|Repeat|1|-|3|Reset|1|}}
|$00
|Repeat: loop when end address is reached. Reset: clears Start and Repeat.
|-
|$11
|{{8BitRegister|L|1|R|1|-|6|}}
|$00
|Left/Right channel output
|-
|$12
|{{8BitRegister|Sample's start address/256 LSB|8}}
|?
|rowspan="4"|All ADPCM addresses must match a 256-byte boundary (bits 0~7 = 0)
|-
|$13
|{{8BitRegister|Sample's start address/256 MSB|8}}
|?
|-
|$14
|{{8BitRegister|Sample's stop address/256 LSB|8}}
|?
|-
|$15
|{{8BitRegister|Sample's stop address/256 MSB|8}}
|?
|-
|$19
|{{8BitRegister|Delta-N (L)|8}}
|?
|rowspan="2"|Playback rate is f = 8M / 12 / 12 / (65535 / Delta-N) = 55555 * (Delta-N / 65535) Hz
|-
|$1A
|{{8BitRegister|Delta-N (H)|8}}
|?
|-
|$1B
|{{8BitRegister|ADPCM-B channel volume|8}}
|?
|Loudest is $FF
|}


=Format=
=Format=


To do.
Requirements:
* ADPCM-A Samples can be any size from '''256 bytes to 1MiB, in 256 bytes steps'''. They must be padded with silence.
* ADPCM-A Samples '''cannot cross 1MB pages''' (the 4 MSBs of the end address must be equal those of the start address). Be sure to organize/map your data correctly.
* ADPCM-B Samples can be any size from '''256 bytes to 16MiB, in 256 bytes steps'''. They must be padded with silence.


=Drifting=
=Drifting=
Line 13: Line 148:
[[File:Adpcm_drift.png|thumb|Decoded ADPCM audio slowly drifting upwards and hitting a chunk of garbage data.]]
[[File:Adpcm_drift.png|thumb|Decoded ADPCM audio slowly drifting upwards and hitting a chunk of garbage data.]]


Since the algorithm is based on the difference between samples, it is prone to drifting if buggy codecs or bad data are used.
Since the codec is based on the difference between samples, it is prone to drifting if buggy codecs or bad data are used.


Clean data should always produce a zero-centered signal when decoded.
Clean data should always produce a zero-centered signal when decoded.
Line 19: Line 154:
If a cartridge has contact issues for example, the YM2610 will read corrupt data and the decoder will make the output value randomly "jump" everywhere, resulting in a horrendous screeching sound even if only one data line is disconnected.
If a cartridge has contact issues for example, the YM2610 will read corrupt data and the decoder will make the output value randomly "jump" everywhere, resulting in a horrendous screeching sound even if only one data line is disconnected.


Many V ROMs contain garbage data at more-or-less regular intervals. Consequently, if the dump is decoded from start to end, the decoder will take the garbage data into account and the decoded audio output will either drift slowly or become brutally offset. This isn't an issue when the game is running because the YM2610 resets the decoder each time a sample is played (also, the [[sound driver]] shouldn't be playing garbage data).
Many V ROMs contain garbage data between valid samples. Consequently, if the dump is decoded from start to end, the decoder will take the garbage data into account and the decoded audio output will either drift slowly or become brutally offset. This isn't an issue when the game is running because the YM2610 resets the decoder each time a sample is played (also, the [[sound driver]] shouldn't be playing garbage data).
 


[[Category:Audio system]]
[[Category:Audio system]]

Latest revision as of 00:29, 8 August 2021

Adaptive Differential Pulse Code Modulation is a lossy audio compression algorithm. It is essentially PCM with dynamic quantizing step adaptation. See [Wikipedia article] for more general informations.

The NeoGeo's YM2610 uses this format for samples stored in the V ROMs or PCM files. Each sample is coded in 4 bits and approximately reconstituted as 12 or 16 bits during playback.

Note that the Yamaha ADPCM format is different from the common IMA and Microsoft ADPCM formats. See ADPCM codecs for encoding and decoding tools.

The NeoGeo CD can't use ADPCM-B.

Status register

Address (Z80 port 4) Data (Z80 port 5) Value on reset
$1C
Bit 7 6 5 4 3 2 1 0
Def B -A6A5A4A3A2A1
$00

Each bit corresponds to an ADPCM channel.

  • Write 1 to reset and mask selected flag
  • Write 0 to unmask selected flag

Masking a flag will prevent it from being raised when a channel reaches its end address. This means it is required to write 1 to clear the flag, then 0 to keep it active.

Flags must be manually cleared, playing a new sample on the channel won't clear it and the channel will stay silent.

ADPCM-A

The ADPCM-A part has 6 channels with a fixed playback frequency of: 8MHz (8M) / 12 (prescaler) / 6 clocks per access / 6 channels = ~18.5185kHz.

Audio is compressed as 4bit per sample and played back as 12bit.

Registers

Address (Z80 port 6) Data (Z80 port 7) Value on reset
$00
Bit 7 6 5 4 3 2 1 0
Def Dump -CH6CH5CH4CH3CH2CH1
$00 'Dump' is the key on/off bit. Write 0 to start playing specified channels and 1 to stop playing.
$01
Bit 7 6 5 4 3 2 1 0
Def - Master volume
$00 Actually an attenuator, $3F is the loudest.
$02
Bit 7 6 5 4 3 2 1 0
Def ?
$00 ? Test register. Ignore or set to $00 for normal operation.
$08~$0D (one for each channel)
Bit 7 6 5 4 3 2 1 0
Def L R-Channel volume
$00 Actually an attenuator, $1F is the loudest. L/R routes the output to the left and/or right channels.
$10~$15 (one for each channel)
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 LSB
$00 All ADPCM addresses must match a 256-byte boundary (bits 0~7 = 0).

Example: if register $18 = $1D and register $10 = $23, the sample's start address will be $1D2300.

$18~$1D (one for each channel)
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 MSB
$00
$20~$25 (one for each channel)
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 LSB
$00
$28~$2D (one for each channel)
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 MSB
$00

ADPCM-B

The ADPCM-B part only has 1 channel, but the playback frequency can be set from 1.85kHz to: 8MHz (8M) / 2 / 12 (prescaler) / 6 clocks per access = ~55.555kHz.

Audio is compressed as 4bit per sample and played back as 16bit.

Registers

See ADPCM for details on this part's operation.

Address (Z80 port 4) Data (Z80 port 5) Value on reset
$10
Bit 7 6 5 4 3 2 1 0
Def Start -Repeat-Reset
$00 Repeat: loop when end address is reached. Reset: clears Start and Repeat.
$11
Bit 7 6 5 4 3 2 1 0
Def L R-
$00 Left/Right channel output
$12
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 LSB
? All ADPCM addresses must match a 256-byte boundary (bits 0~7 = 0)
$13
Bit 7 6 5 4 3 2 1 0
Def Sample's start address/256 MSB
?
$14
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 LSB
?
$15
Bit 7 6 5 4 3 2 1 0
Def Sample's stop address/256 MSB
?
$19
Bit 7 6 5 4 3 2 1 0
Def Delta-N (L)
? Playback rate is f = 8M / 12 / 12 / (65535 / Delta-N) = 55555 * (Delta-N / 65535) Hz
$1A
Bit 7 6 5 4 3 2 1 0
Def Delta-N (H)
?
$1B
Bit 7 6 5 4 3 2 1 0
Def ADPCM-B channel volume
? Loudest is $FF

Format

Requirements:

  • ADPCM-A Samples can be any size from 256 bytes to 1MiB, in 256 bytes steps. They must be padded with silence.
  • ADPCM-A Samples cannot cross 1MB pages (the 4 MSBs of the end address must be equal those of the start address). Be sure to organize/map your data correctly.
  • ADPCM-B Samples can be any size from 256 bytes to 16MiB, in 256 bytes steps. They must be padded with silence.

Drifting

Decoded ADPCM audio slowly drifting upwards and hitting a chunk of garbage data.

Since the codec is based on the difference between samples, it is prone to drifting if buggy codecs or bad data are used.

Clean data should always produce a zero-centered signal when decoded.

If a cartridge has contact issues for example, the YM2610 will read corrupt data and the decoder will make the output value randomly "jump" everywhere, resulting in a horrendous screeching sound even if only one data line is disconnected.

Many V ROMs contain garbage data between valid samples. Consequently, if the dump is decoded from start to end, the decoder will take the garbage data into account and the decoded audio output will either drift slowly or become brutally offset. This isn't an issue when the game is running because the YM2610 resets the decoder each time a sample is played (also, the sound driver shouldn't be playing garbage data).