ADSR Behavior Consensus?

Audio and Music (Sound Processing Unit) based area of development, including VAB, XA, etc
Post Reply
KiddCabbage
What is PSXDEV?
What is PSXDEV?
Posts: 4
Joined: Feb 08, 2024

ADSR Behavior Consensus?

Post by KiddCabbage » February 8th, 2024, 6:43 am

Hello,

I've been looking into the PSX's SPU to try to emulate its sound and behavior; not by opening up the hardware and running tests, but by researching the findings that others have had about it. Since most of this discussion has seemed to have happened long ago, and many of the projects (like Highly Experimental) have been discontinued decades ago, the only real leads I've had are through digging through open source emulator code to see what I can come across and learn.

A big hurdle I've come across is to understand exactly how the SPU's ADSR behaves. I understand the parameters that the game can feed to the SPU (Attack rate, release mode, etc.) from some writeups I've found, however every open source project I've found seems to handle these parameters differently.

From P.E.Op.S, it seems they're referencing some calculations from James Higgs and Neill Corlett some 20+ years ago, but considering Neill authored Highly Experimental and Higgs made some measuring software, it seems trustworthy:


Duckstation has its own code for an ADSR step lookup table, and I'm not sure where this was sourced. The creator I guess had some community problems a couple years ago and went hermit, so I can't find a way to ask him where he derived these calculations:


Beetle (Libretro's fork of Mednafx) has its ADSR calculations handled at runtime (yikes), rather than by a lookup table like the other two. Again, no idea where these calcs came from.


And BodbDearg's PSX Sampler VST, based on his port of Doom, Psydoom, has its own more primitive ADSR calculations:


So I guess the point is - does anyone have any insight into research regarding accurate behavior of the SPU? I'm guessing these guys didn't all collectively get these calculations out of nowhere, but there is some sort of documentation or testing that they're all trying to approximate? Any good place to uncover any more truth on the issue?

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 552
Joined: Nov 12, 2012
Contact:

Post by nocash » February 8th, 2024, 9:04 am

The best method is to emulate the SPU on the playstation itself. And then capture the real hardware's waveforms (from reverb buffer, or from the SPU status registers), and compare them against the emulated waveforms.

A basic test would be to display the captured & emulated waveforms on the screen, and check if they do look identical (which should be good enough for most purposes). The specs in psxspx are based on that approach.

Or alternately, one could compare the 16bit values with each other to ensure binary-perfect results with exact same timings and rounding errors as on real hardware.

In practice there are some obstacles: The SPU output is 44kHz, the reverb is only 22kHz, and the CPU is 33MHz (which may yield different results when changing SPU registers a few cycles earlier or later). And the tests should cover all corner cases, with different SPU register values, written at different SPU states, and with different ADPCM samples, and whatever else.

KiddCabbage
What is PSXDEV?
What is PSXDEV?
Posts: 4
Joined: Feb 08, 2024

Post by KiddCabbage » February 9th, 2024, 4:40 am

Hey! Thanks for the response and information.

I have a few thoughts reading your reply:

The first thought is - how do I, as an owner of a couple Playstations, capture this data out of the hardware, like the reverb buffer? Does this require much specialized hardware or knowledge? Outside of a decent amount of soldering, working with hardware is outside of my element - though if it's something I can figure out, you are correct that this really does sound like the most accurate way to collect data.

Second thought is - is this reinventing the wheel at this point? I am referencing a handful of codebases, seemingly none of them finding a consensus of the "right" algorithm. Neill Corlett obviously knew a lot. Duckstation is referencing Dr Hell, who obviously knew a lot and came up with something different. However, I am unaware of the research that went into finding these algorithms in the first place. Perhaps someone (like yourself?) has already done these procedures and I can reference those, or verify a trustworthy algorithm/data lookup for this. I've been reading the SPU section of psx-spx a ton over the last few days, but I haven't seen anything specifically talking about how the values of the ADSR map to the SPU's behavior in setting the voice's level.

Third thought is the wonder if I'm going through this hardware testing process the best kinds of data to work with. I'm assuming there isn't a perfect testing software or anything created to run on hardware to produce the easiest-to-read results? When I'm thinking about determining voice envelope behavior, I feel like the easiest data to work with would be an audio clip with all of the samples at full-scale, playing only that one voice. Then when that voice is put into something like the reverb buffer, I would assume the waveform would just outline the scaling of the envelope 1:1.

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 552
Joined: Nov 12, 2012
Contact:

Post by nocash » February 11th, 2024, 1:54 am

KiddCabbage wrote: February 9th, 2024, 4:40 am Does this require much specialized hardware or knowledge?
No, nothing special (other than having a way to run EXE files on the console, preferably without burning CDRs for each test).
KiddCabbage wrote: February 9th, 2024, 4:40 am I've been reading the SPU section of psx-spx a ton over the last few days, but I haven't seen anything specifically talking about how the values of the ADSR map to the SPU's behavior in setting the voice's level.
I might have forgotten to document something... but the specs are looking more or less complete. Basically, you take the selected Step/Shift values for the current ADSR phase, and feed them to the ADSR generator:

Code: Select all

Envelope Operation depending on Shift/Step/Mode/Direction
  AdsrCycles = 1 SHL Max(0,ShiftValue-11)
  AdsrStep = StepValue SHL Max(0,11-ShiftValue)
  IF exponential AND increase AND AdsrLevel>6000h THEN AdsrCycles=AdsrCycles*4
  IF exponential AND decrease THEN AdsrStep=AdsrStep*AdsrLevel/8000h
  Wait(AdsrCycles)              ;cycles counted at 44.1kHz clock
  AdsrLevel=AdsrLevel+AdsrStep  ;saturated to 0..+7FFFh
And then, for the final output, multiply everything together, like this: Output=SampleValue*VoiceVolume*AdsrVolume*MasterVolume.
KiddCabbage wrote: February 9th, 2024, 4:40 am Dr Hell, who obviously knew a lot and came up with something different.
I haven't compared the different ADSR source code functions, and don't know if they are really different, or if they are just different ways to get the same result. Dr Hell was the first person who had documented the Reverb formulas (and also the first person who knew everything else - there've been a couple of cases where I had rev engineered stuff, being convinced that nobody had ever done that yet, only to find out that it was already implemented in the xebra emulator - I guess xebra must be either based on outstanding reverse engineering, or on having access to secret japanese hardware references).
KiddCabbage wrote: February 9th, 2024, 4:40 am I feel like the easiest data to work with would be an audio clip with all of the samples at full-scale, playing only that one voice. Then when that voice is put into something like the reverb buffer
Yes, like that. But for ADSR testing it's easier to just read the current ADSR volume from the SPU status registers (in sync with hardware timers), so there's no need to rip that data from the reverb buffer.
KiddCabbage wrote: February 9th, 2024, 4:40 am is this reinventing the wheel at this point?
Give me some days, I'll upload my old SPU test program. It's merely testing 10 different ADSR waveforms, but that should be good enough to see if any PSX emulators are getting it the ADSR stuff completely wrong.
I don't know any other SPU test software.

KiddCabbage
What is PSXDEV?
What is PSXDEV?
Posts: 4
Joined: Feb 08, 2024

Post by KiddCabbage » February 19th, 2024, 9:44 pm

Just following up to say a big thank you - this writeup on the ADSR behavior is great - really straightforward compared to most other things I'd seen.

For testing sounds without having to burn a CD every time, at this point I guess it's about time I bite the bullet and get an XStation. This is sort of what you're talking about that would let me run some of these exe files without having to burn a disk, correct?

I'm looking forward to your SPU test program - that should help me test some of this immensely.

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 552
Joined: Nov 12, 2012
Contact:

Post by nocash » February 22nd, 2024, 2:36 pm

KiddCabbage wrote: February 19th, 2024, 9:44 pm Just following up to say a big thank you - this writeup on the ADSR behavior is great - really straightforward compared to most other things I'd seen.
Yipieh. I guess it was almost a bit too straightforward, lacking all those expected confusing descriptions ; )
KiddCabbage wrote: February 19th, 2024, 9:44 pm I'm looking forward to your SPU test program - that should help me test some of this immensely.
Okay, here it is, http://problemkaputt.de/psx-diag.htm for the ADSR stuff, go to SPU TESTS, then to SPU ADSR TESTS.
The tests should draw several gray graphs, and then several colored graphs that should overlap the gray ones (except, the right half of the 3rd and 4th graph don't overlap properly, the colored graphs extend horizontally, but the gry graphs descend in the right half, that's a bug in the diag tool).
To see how the graphs should look like: run diag.exe on real hardware, or in no$psx.
KiddCabbage wrote: February 19th, 2024, 9:44 pm For testing sounds without having to burn a CD every time, at this point I guess it's about time I bite the bullet and get an XStation. This is sort of what you're talking about that would let me run some of these exe files without having to burn a disk, correct?
Sorts of, the reusable SD cards are fine, but it doesn't seem to have any direct data upload feature, so you are back to SD card swapping, and SD card burning, which is almost as uncomfortable as CDR burning.
Back then, all PCs did have (and my own PCs still have) built-in standard GPIO parallel/printer ports, which worked perfectly for uploading EXE files to consoles (in case of the PSX, most cheat devices did include a parallel port on the PSX side).
But today, there are tons of different GPIO ports, but there seems to be no real standard. The only option would be to build or buy some random GPIO, and then write your own transfer software for it.

KiddCabbage
What is PSXDEV?
What is PSXDEV?
Posts: 4
Joined: Feb 08, 2024

Post by KiddCabbage » March 3rd, 2024, 6:53 pm

Hey nocash, Got the exe and I've been able to play with your SPU diagnosis tool. Good stuff, though I'm a little confused on exactly how to utilize what I'm seeing! :D

I've actually just lifted a pad from my SPU, so I've got a friend with better soldering tools doing a repair for me, and then I can get back to work. While he's at it, I'm having him throw in an XStation, just so that I can do SD writes to the software, which should be a little easier than burned disks. :)

In the mean time, I wrote a little program using the PSYQo SDK to expose all envelope parameters to the SPU, for recording purposes (though I need to figure out how to get proper multiple offsets into uploading different waveforms to the SPU): https://github.com/jdperos/PSXSpuTest/

I also need to write a program for Arduino or RPi to capture the I2S data off the SPU or DAC. Then using full-scale audio waveforms, I should be able to just capture the I2S data with different ADSR settings, and get exact readings for an accurate LUT or algorithm to generate it.

What do you think?

User avatar
nocash
Verified
PSX Aficionado
PSX Aficionado
Posts: 552
Joined: Nov 12, 2012
Contact:

Post by nocash » March 5th, 2024, 7:22 am

KiddCabbage wrote: March 3rd, 2024, 6:53 pm I'm a little confused on exactly how to utilize what I'm seeing! :D
Why? Just run the diag.exe in emulators and check if the ADSR graphs are looking right. I haven't tried that, but it would be interesting if the four SPU emulations that you had posted above are actually producing different ADSR graphs.
That is, if the SPU emu is part of a full PSX emulator (if it's a plain SPU emu for raw audio playback then it won't work).
KiddCabbage wrote: March 3rd, 2024, 6:53 pm I also need to write a program for Arduino or RPi to capture the I2S data off the SPU or DAC.
Good idea, that might give some more insighs into the final audio mixing stage, including final saturations or final rounding errors.
It's also having two disadvantages: In case of errors, using external (or internal) capture might be slightly more difficult to tell if the error had occured in adsr-stage, adpcm-stage, or whichever-stage, or timings inbetween those stages. And external capture makes it impossible to create a self-test tool like diag.exe, as it won't work without (emulating) the external capture hardware.

scphscpe
What is PSXDEV?
What is PSXDEV?
Posts: 1
Joined: Mar 14, 2024

Post by scphscpe » March 14th, 2024, 7:33 pm

Tried this tool in some emulators:
Xebra - seems like this emulator is unable to read the needed data from SPU so it just shows straight lines.
Mednafen - this emulator often hates anything that is not a commercially released game, so it refuses to load the EXE file and shows its bullshit message VIDEO STANDARD MISMATCH.
Duckstation - only some ADSR envelopes look right.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests