Small Sega CD PCM question: sample rates
Moderator: Mask of Destiny
Small Sega CD PCM question: sample rates
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.
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.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
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.
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.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Ah - I knew I was off there. Great explanation.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.
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:
and the code to load it:
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?
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
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)
-
- Very interested
- Posts: 2440
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
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.
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
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
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
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
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.
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.
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.