An update:

There's actually a "Pitch" value in SGL sound effects that you can manipulate to play the sound back at different rates.

I did see this before I looked at the Rockin'Bs code, but I hadn't figured out how to manipulate it. I don't think I ever would have, it's really complex.

This unfortunately does not comply directly with a sample rate.

Fortunately Rockin'B has some code that can take an input sample rate, and convert that to an output pitch for SGL sound.

This is pretty dang useful, but it uses double-precision values so the Saturn cannot compute it itself (plus, where would you even know the sample rate?)

To get around that, I just used an online C compiler. With that, I can generate a table of common sample rates and convert those to pitch rates.

`#include <stdlib.h>`

#include <stdio.h>

#include <math.h>

#define PCM_toPitch(OCT, FNS) ((FNS & 0x03FF) | ((OCT & 0xF) << 11))

#define PCM_toOCT(pitch) ((pitch & 0x7800) >> 11)

#define PCM_TIMES 1.000577789

// SOURCE: The Rockin' B, Rockin' B Saturn Libraries, RB_PCM.C, line 766

unsigned short PCM_computePitch(double sampleRate)

{

double c, s;

int OCT, FNS;

// Fn = Fo * 2^(n/1200)

// compute necessary slowdown / speedup

// assuming a base frequency of 44100 Hz

// Fn / Fo = 2^(n/1200)

// with Fo = 44100 Hz, the saturn base sample frequency

s = sampleRate / 44100.0;

// printf("s = %f\n", s);

// compute the pitch to this(cents)

// n = log(s) / log(PCM_TIMES);

// log2(Fn / Fo) * 1200 = n

c = (log(s) / log(2)); // * 1200.0;

// printf("c1 = %f\n", c);

if(c >= 0) {

// compute OCT

OCT = (int)c;

// compute FNS

c -= (double)OCT;

} else {

// compute OCT

OCT = (int)c;

if(c < OCT)

OCT -= 1;

// compute FNS

c = c - ((double)OCT);

// respect to new base frequency

// s = sampleRate / (44100.0 / (1 - OCT));

// n is now >= 0

// c = (log(s) / log(2));

}

OCT &= 0xF;

// printf("OCT = %x\n", OCT);

// compute FNS

c *= 1200.0;

// printf("c2 = %f\n", c);

// remove OCT from cents,

// it's a seperate value

// the argument needs to be in range 0 <= a < 1200

// printf("(c / 1200.0) = %f\n", (c / 1200.0));

// printf("(double)((int)(c / 1200.0)) = %f\n", (double)((int)(c / 1200.0)));

// printf("pow arg = %f\n", (c / 1200.0) - (double)((int)(c / 1200.0)));

// printf("pow() = %f\n", pow(2, (c / 1200.0) - (double)((int)(c / 1200.0))));

FNS = ((int)(1024.0 * (pow(2, (c / 1200.0) ) - 1.0))) & 0x3FF;

// printf("FNS = %i\n", FNS);

// interpret

// return ((int)(1024.0 * (pow(2, c/1200.0) - 1.0))) & (0x3FF + (0xF << 11));

return PCM_toPitch(OCT, FNS);

}

void main(void){

int Rate = 18900;

int Pitch;

Pitch = PCM_computePitch(Rate);

printf("(%i)", Pitch);

}

On this website:

https://www.onlinegdb.com/online_c_compilerYou can modify the sound data like this:

__jo_internal_pcm[(int)channel].pitch = [pitch number];

Table of simple rates:

`44.10 KHz 0 Pitch`

37.80 KHz (31451) Pitch

30.72 KHz (31122) Pitch

22.05 KHz (30720) Pitch

18.90 KHz (29403) Pitch

16.00 KHz (29134) Pitch

11.00 KHz (27643) Pitch

08.00 KHz (27086) Pitch

With this, you can play sound at any sample rate using SGL.

And I should be able to continue my efforts and forge some sort of sound-streaming system using it.

Well, since I got the SBL STM library to cooperate, maybe? Probably not...

On another note: Why did I finally give up on SBL PCM-ADPCM library?

Well, I got it to run playback code errorless, meaning it did not report an error playing back the sound.

But it did not play any sound, even on real hardware, with the interrupt registered. So I had nowhere left to go. Code was Errorless, crashless code that doesn't work is the worst. And you know that's what most game bugs are...