[Sonic 2/3K] How to use 8-bit PCM for DAC rather than 4-bit DPCM

Discussion in 'Tutorials' started by RepellantMold, Feb 6, 2025.

  1. RepellantMold

    RepellantMold Newcomer Trialist

    Joined:
    Jan 9, 2024
    Messages:
    8
    Location:
    Cali-four-nya
    Have you ever wanted true PCM quality from your drums? This tutorial is for you!
    Before you start, you must be aware that this will severely balloon up sample sizes as you're going from 4-bit DPCM to 8-bit PCM so good luck trying to juggle Z80 bank space around (unless you have automatic bank switching).

    First, you'll need dpcm2pcm from SMPS Research Pack by ValleyBell to decompress the samples from 4-bit DPCM to 8-bit PCM (or grab them from Sonic 2 Clone Driver v2), then, follow the guide in the spoilers for your specific game.

    First, go into s2.sounddriver.asm.
    at zStartDAC, remove this line
    Code:
            ld    iy,zDACDecodeTbl
    
    as iy is gonna be unused after these changes.
    next at zWriteToDAC, remove these lines
    Code:
        rlca
        rlca
        rlca
        rlca
        and    0Fh            ; UPPER 4-bit offset into zDACDecodeTbl
        ld    (.highnybble+2),a    ; store into the instruction after .highnybble (self-modifying code)
        ex    af,af'            ; shadow register 'a' is the 'd' value for 'jman2050' encoding
    
    ; zloc_18B
    .highnybble:
        add    a,(iy+0)        ; Get byte from zDACDecodeTbl (self-modified to proper index)      
    
    and remove
    Code:
            ex    af,af'
    
    as we do not need to be swapping registers since we don't need to be doing decoding anymore.
    after
    Code:
            ld    (zYM2612_D0),a
    
    next, remove these lines
    Code:
            and    0Fh            ; LOWER 4-bit offset into zDACDecodeTbl
        ld    (.lownybble+2),a    ; store into the instruction after .lownybble (self-modifying code)
        ex    af,af'            ; shadow register 'a' is the 'd' value for 'jman2050' encoding
    
    ; zloc_1A8
    .lownybble:
        add    a,(iy+0)        ; Get byte from zDACDecodeTbl (self-modified to proper index)
    
    and remove
    Code:
            ex    af,af'
    
    This change will also make the drums very low pitched from how much code was changed!
    If you're using older disassemblies, subtract the pitch values by 10.
    If you're using current disassemblies, then change the magic number in dpcmLoopCounter to 179 (since we subtracted 110 cycles total)
    Please note that the stock pitches will make the value overflow!

    First, go to "Sound/Z80 Sound Driver.asm"
    at .dac_idle_loop under zPlayDigitalAudio, remove
    Code:
            ld    iy, DecTable            ; iy = pointer to jman2050 decode lookup table
    
    at .dac_playback_loop, remove
    Code:
            ; Want only the high nibble now, so shift it into position
            rlca
            rlca
            rlca
            rlca
            and    0Fh            ; Get only low nibble (which was the high nibble originally)
            ld    (.sample1_index+2), a    ; Store into following instruction (self-modifying code)
            ld    a, c            ; a = c
    
    .sample1_index:
            add    a, (iy+0)        ; Self-modified code: the index offset is not zero, but what was set above
    
    then remove
    Code:
            ld    c, a            ; Set c to the new value of a
    
    also remove
    Code:
            and    0Fh            ; Want only the low nibble
            ld    (.sample2_index+2), a    ; Store into following instruction (self-modifying code)
            ld    a, c            ; a = c
    
    ;.sample2_index:
            add    a, (iy+0)        ; Self-modified code: the index offset is not zero, but what was set above
    
    and
    Code:
            ld    c, a            ; Set c to the new value of a
    
    If you're using current disassemblies, then change the magic number in dpcmLoopCounter to 225 (since we subtracted 72 cycles total)
     
    Last edited: Mar 2, 2025
  2. RobiWanKenobi

    RobiWanKenobi Python Developer and ASM enthusiast Member

    Joined:
    Sep 10, 2022
    Messages:
    137
    Location:
    West United States (MDT/MST)
    I've had 8-Bit PCM samples in S2 long before this guide existed, lol

    I didn't even use clone driver.

    EDIT: What I'm about to say here has been resolved


    ALSO, if you want the samples already in 8-bit PCM, they are in Clone Driver
     
    Last edited: Mar 5, 2025
    RepellantMold likes this.
  3. Devon

    Devon Please do not contact me, overwhelmed with stuff Member

    Joined:
    Aug 26, 2013
    Messages:
    1,470
    Location:
    your mom
    I mean, the Clone Driver is a 68000 driver, and perhaps someone may want to stick with a Z80 driver? This could still be useful for them.
     
  4. RobiWanKenobi

    RobiWanKenobi Python Developer and ASM enthusiast Member

    Joined:
    Sep 10, 2022
    Messages:
    137
    Location:
    West United States (MDT/MST)
    I just meant the PCM files.
     
  5. RobiWanKenobi

    RobiWanKenobi Python Developer and ASM enthusiast Member

    Joined:
    Sep 10, 2022
    Messages:
    137
    Location:
    West United States (MDT/MST)
    Other beneficial things to add:

    DAC Banks (for Sonic 2):

    Clownacy has described how to do it here.
    https://forums.sonicretro.org/index.php?threads/making-sonic-2s-sound-driver-good.34124/
     
    Last edited: Mar 5, 2025
    RepellantMold and PeanutNoceda like this.