C-1 is said to have a period of 856, which implies a frequency of 4181.7 Hz.

That sounds correct. I think it's just your interpretation of what frequency means in this context is a bit off. A frequency of 4181 Hz doesn't mean that the

*whole* sample repeats 4181 times a second. The result of this formula is a

*sample rate*, i.e. it's the frequency at which the sample position is incremented - it means that 4181 sampling points will play

*per second*. So if your sample is 4181 samples long, its duration will be exactly one second (if it was 8362 points long, it would take two seconds to play, and so on).

What OpenMPT does is first translate the period into frequency (the same way you do), and then converts this frequency into a ratio of this sample mix rate and the output mix rate, and uses this to determine how fast to increment the sample. Let's choose more simple numbers for the sake of an example: Suppose your output mix rate is 48000 Hz (that would be a very common value, alternatively "CD quality" 44100 Hz), and period to frequency conversion gave you a sample rate of 4800 Hz (somewhere between D-1 and D#1). The ratio between those two numbers is 4800/48000 = 0.1, i.e. for every increment in the mixer's output, you advance the offset at which you read from your sample data at 0.1.

Small example:

`time | offset`

0 | 0

1 | 0.1

2 | 0.2

3 | 0.3

...

9 | 0.9

10 | 1.0

11 | 1.1

...

after one second...

47999 | 4799.9

48000 | 4800.0

48001 | 4800.1

....

Now the next thing you might be asking yourself is "how do I read sample data at offset 0.5", and the answer is "it depends". An old-skool MOD player will simply truncate the result, i.e. round down. A more sophisticated player will interpolate the output if the offset is fractional, for which it will use at least the previous and next sample point (linear interpolation) or even more surrounding sample points (e.g. sinc interpolation). But you shouldn't care about that for now, one step at a time.