Small Sega CD PCM question: sample rates

Ask anything your want about Mega/SegaCD programming.

Moderator: Mask of Destiny

Post Reply
andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Small Sega CD PCM question: sample rates

Post by andlabs » Fri Aug 27, 2010 7:40 pm

Hi. I'm just wondering how the Sega CD PCM chip's FDH/FDL registers correspond to sample rates, namely if FDH==4 and FDL==$15 (hex). I understand what the chip is doing (similar to a rudimentary out[x]=in[x*inrate/outrate] resampler) but I don't understand how to convert the resultant increment back into a sample rate. Thanks.

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Sat Aug 28, 2010 3:01 am

I have it as: Sample rate = FD * PCM clock / 2048, where PCM clock = 12.5 MHz / 384 = 32552 Hz approx.

SR = (FDH * 256 + FDL) * 12500000 / (384 * 2048)

andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Post by andlabs » Sat Aug 28, 2010 3:57 am

Thanks, that was exactly it — Rex Sabio's handwritten formula had meaning after all =P

For the record the value for my FDH/FDL was 16609.8276774089 hz — the sampling rate of most of the PCM samples in Sonic CD.

andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Post by andlabs » Mon Aug 30, 2010 5:37 pm

Okay, sorry for the double post but does this formula hold for higher values of the FD register? I have a sample which is usually played around the area where C would be FDH = $42 and FDL = $06 and I'm getting 268650 hz with that, which is outrageously high even for current hardware(?), and wrong when I go to put it in Audacity. I tried putting it in at a much lower octave (around 33khz) but I get not another C but rather what appears to be G quarter sharp, and at the frequency I listed above I get a G#. What could be the issue now? Do I need a different formula for these higher octaves? Thanks.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Tue Aug 31, 2010 12:20 am

I think that 2048 in the formula above is the loop length of the sample. You have to adjust both the FD and the sample length to keep the final rate under 32kHz.

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Tue Aug 31, 2010 8:36 am

The PCM address registers each have an 11-bit fractional component (2^11 = 2048). Technically, the sampling rate is fixed at 32KHz, and FD serves as an increment to the address register.

In a sense, you could say that a PCM RAM pointer is advanced by FD/2048 bytes at every clock (32KHz). So, if FD = 2048, the pointer advances exactly 1 byte per clock and therefore samples each consecutive byte until the loop ends (when sample data = 0xFF), at which point sampling continues from the loop address.

Increasing FD greater than 2048 will increase the playback rate but not the sampling rate. Also, special consideration must be given to the loop end since a single sample 0xFF could potentially be skipped over depending on FD. For this, you could have several 0xFF samples in a row at the end of the loop.

As for FDH=0x42 and FDL=0x06: that's not very useful. It would make more sense if FDH=0x06 and FDL=0x42. Note that FDL comes before FDH in the register set.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Sep 01, 2010 1:16 am

TascoDLX wrote:The PCM address registers each have an 11-bit fractional component (2^11 = 2048). Technically, the sampling rate is fixed at 32KHz, and FD serves as an increment to the address register.

In a sense, you could say that a PCM RAM pointer is advanced by FD/2048 bytes at every clock (32KHz). So, if FD = 2048, the pointer advances exactly 1 byte per clock and therefore samples each consecutive byte until the loop ends (when sample data = 0xFF), at which point sampling continues from the loop address.

Increasing FD greater than 2048 will increase the playback rate but not the sampling rate. Also, special consideration must be given to the loop end since a single sample 0xFF could potentially be skipped over depending on FD. For this, you could have several 0xFF samples in a row at the end of the loop.

As for FDH=0x42 and FDL=0x06: that's not very useful. It would make more sense if FDH=0x06 and FDL=0x42. Note that FDL comes before FDH in the register set.
Ah - I knew I was off there. Great explanation. :D

andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Post by andlabs » Mon Oct 11, 2010 7:30 pm

Sorry for the delayed response, but I'm getting confused by some of the posts. I understand what TascoDLX means, and in fact I can use that knowledge later, however I'm still not understanding what's happening when the FD goes above 2048 — I still have to sample at 32Khz and resample it myself later in, say, another song (as an example)? Here is the frequency table:

Code: Select all

ROM:00040FD4 NoteFDEquivs:   dc.w 0                  ; DATA XREF: DoNote+8o
ROM:00040FD4                                         ; rest
ROM:00040FD6                 dc.w $104               ; C0
ROM:00040FD8                 dc.w $113               ; C#0
ROM:00040FDA                 dc.w $124               ; D0
ROM:00040FDC                 dc.w $135               ; D#0
ROM:00040FDE                 dc.w $148               ; E0
ROM:00040FE0                 dc.w $15B               ; F0
ROM:00040FE2                 dc.w $170               ; F#0
ROM:00040FE4                 dc.w $186               ; G0
ROM:00040FE6                 dc.w $19D               ; G#0
ROM:00040FE8                 dc.w $1B5               ; A0
ROM:00040FEA                 dc.w $1D0               ; A#0
ROM:00040FEC                 dc.w $1EB               ; B0
ROM:00040FEE                 dc.w $208               ; C1
ROM:00040FF0                 dc.w $228               ; C#1
ROM:00040FF2                 dc.w $248               ; D1
ROM:00040FF4                 dc.w $26B               ; D#1
ROM:00040FF6                 dc.w $291               ; E1
ROM:00040FF8                 dc.w $2B8               ; F1
ROM:00040FFA                 dc.w $2E1               ; F#1
ROM:00040FFC                 dc.w $30E               ; G1
ROM:00040FFE                 dc.w $33C               ; G#1
ROM:00041000                 dc.w $36E               ; A1
ROM:00041002                 dc.w $3A3               ; A#1
ROM:00041004                 dc.w $3DA               ; B1
ROM:00041006                 dc.w $415               ; C2
ROM:00041008                 dc.w $454               ; C#2
ROM:0004100A                 dc.w $497               ; D2
ROM:0004100C                 dc.w $4DD               ; D#2
ROM:0004100E                 dc.w $528               ; E2
ROM:00041010                 dc.w $578               ; F2
ROM:00041012                 dc.w $5CB               ; F#2
ROM:00041014                 dc.w $625               ; G2
ROM:00041016                 dc.w $684               ; G#2
ROM:00041018                 dc.w $6E8               ; A2
ROM:0004101A                 dc.w $753               ; A#2
ROM:0004101C                 dc.w $7C4               ; B2
ROM:0004101E                 dc.w $83B               ; C3
ROM:00041020                 dc.w $8B0               ; C#3
ROM:00041022                 dc.w $93D               ; D3
ROM:00041024                 dc.w $9C7               ; D#3
ROM:00041026                 dc.w $A60               ; E3
ROM:00041028                 dc.w $AF8               ; F3
ROM:0004102A                 dc.w $BA8               ; F#3
ROM:0004102C                 dc.w $C55               ; G3
ROM:0004102E                 dc.w $D10               ; G#3
ROM:00041030                 dc.w $DE2               ; A3
ROM:00041032                 dc.w $EBE               ; A#3
ROM:00041034                 dc.w $FA4               ; B3
ROM:00041036                 dc.w $107A              ; C4
ROM:00041038                 dc.w $1186              ; C#4
ROM:0004103A                 dc.w $1280              ; D4
ROM:0004103C                 dc.w $1396              ; D#4
ROM:0004103E                 dc.w $14CC              ; E4
ROM:00041040                 dc.w $1624              ; F4
ROM:00041042                 dc.w $1746              ; F#4
ROM:00041044                 dc.w $18DE              ; G4
ROM:00041046                 dc.w $1A38              ; G#4
ROM:00041048                 dc.w $1BE0              ; A4
ROM:0004104A                 dc.w $1D94              ; A#4
ROM:0004104C                 dc.w $1F65              ; B4
ROM:0004104E                 dc.w $20FF              ; C5
ROM:00041050                 dc.w $2330              ; C#5
ROM:00041052                 dc.w $2526              ; D5
ROM:00041054                 dc.w $2753              ; D#5
ROM:00041056                 dc.w $29B7              ; E5
ROM:00041058                 dc.w $2C63              ; F5
ROM:0004105A                 dc.w $2F63              ; F#5
ROM:0004105C                 dc.w $31E0              ; G5
ROM:0004105E                 dc.w $347B              ; G#5
ROM:00041060                 dc.w $377B              ; A5
ROM:00041062                 dc.w $3B41              ; A#5
ROM:00041064                 dc.w $3EE8              ; B5
ROM:00041066                 dc.w $4206              ; C6
ROM:00041068                 dc.w $4684              ; C#6
ROM:0004106A                 dc.w $4A5A              ; D6
ROM:0004106C                 dc.w $4EB5              ; D#6
ROM:0004106E                 dc.w $5379              ; E6
ROM:00041070                 dc.w $58E1              ; F6
ROM:00041072                 dc.w $5DE0              ; F#6
ROM:00041074                 dc.w $63C0              ; G6
ROM:00041076                 dc.w $68FF              ; G#6
ROM:00041078                 dc.w $6EFF              ; A6
ROM:0004107A                 dc.w $783C              ; A#6
ROM:0004107C                 dc.w $7FC2              ; B6
ROM:0004107E                 dc.w $83FC              ; C7
ROM:00041080                 dc.w $8D14              ; C#7
ROM:00041082                 dc.w $9780              ; D7
ROM:00041084                 dc.w $9D80              ; D#7
ROM:00041086                 dc.w $AA5D              ; E7
ROM:00041088                 dc.w $B1F9              ; F7
ROM:0004108A                 dc.w $BBBA              ; F#7
ROM:0004108C                 dc.w $CC77              ; G7
ROM:0004108E                 dc.w $D751              ; G#7
ROM:00041090                 dc.w $E333              ; A7
ROM:00041092                 dc.w $F0B5              ; A#7
and the code to load it:

Code: Select all

ROM:00040FCC                 lea     ($FF0000).l,a4
;...
ROM:00040A7C                 move.b  d1,5(a4)
ROM:00040A80                 lsr.w   #8,d1
ROM:00040A82                 move.b  d1,7(a4)
So eventually I will wind up with a point where the FD value is going to be MUCH greater than 2048; what exactly would I do there? Or am I still not understanding?

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Tue Oct 12, 2010 2:46 pm

If the data is freq settings value is 11bits you just AND out the top bits, and see what you got left...

EDIT: never mind...

The 11 bits are the fraction, top 5 bits are whole value, which get added directly to the current address. so if the whole part is two, then 2 samples are skipped in every cycle, the PCM data is played at 2x the speed... at least so I understand it.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Post by andlabs » Thu Oct 14, 2010 11:36 pm

In that case, let me see if I understand properly:

The FD value is split as so:
F = FD & 0x7FF; // 2047
MULT = (FD >> 11) & 0x1F;

With this, I get
base_sample_rate = F * 12500000 / (384 * 2048)

and the final sample rate is base_sample_rate * MULT?

I just tried it on a bass sample which appears to have FD = $107A at its usual C4, and I got 3878hz, which is much lower than it needs to be

Gigasoft
Very interested
Posts: 95
Joined: Fri Jan 01, 2010 2:24 am

Post by Gigasoft » Thu Oct 14, 2010 11:51 pm

No, just use the value as it is: FD * 12500000 / 786432.
$107A then becomes 67043.3 Hz.

andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Post by andlabs » Fri Oct 15, 2010 9:22 pm

Yes, unfortunately that is too high of a frequency, and the note comes out wrong. Here is the sample after converting to 8-bit unsigned. It should be a bass note.

andlabs
Very interested
Posts: 62
Joined: Sat Aug 08, 2009 4:44 pm

Post by andlabs » Wed Nov 03, 2010 5:13 pm

Well I played around with it a bit more, especially with what TascoDLX said about 32khz, and... turns out every sample is tuned to something completely different, meaning I'd have had to try random values from that list within the $0..$7C4 range, though the value for $7C4 (the closest to 32khz formally defined in the sound driver) gives me a good place to start. Thanks guys after all!

And yes, now I understand what TascoDLX meant. I'll keep this in mind in the near future, as I do have something PCM-related planned.

Post Reply