When working on SMPSPlay and DEPlay there was always one thing that bothered me: the DAC frequency
It's something I couldn't just get right, so I decided to do some research.
I startet with Oerg866's SMPS Player, which uses jman2050's DAC driver:
At first I made an SMPS file that plays a few DAC sounds and made each sound play the same sample, but with different DAC rates.
Then I used MESS to make a VGM of it. (MESS because MAME's timing system is extremely accurate.)
After that I wrote a small tool in VB that reads that VGM and calculated the frequency of each sound.
Finally I made another small VB tool that recalculated the formula FreqHz = BaseVal / (RateBase + DACRate) for the DAC rates I logged. With this tool I tested values for RateBase until I found a perfect one. (I made it recalculate BaseVal with the tested frequency of rate 01 and RateBase.)
Then I did the same with plain Sonic 1, Sonic 2, and Barver Battle Saga (because I already had its pointers) for the Data East driver.
And here are my results:
(The columns are DACRate, logged DAC samples, length of the DAC sound in VGM ticks (44100 Hz), DAC samples per VGM sample, DAC frequency.)
All formulas are accurate enough that the difference between tested and recauculated (DAC samples per VGM sample) is <= 0.2 for all rates. (except for Sonic 2 with gaps)
The Sonic 2 driver does all work on the Z80, so it needs to interrupt the DAC stream every frame to do update the music engine. [without gaps] means, that I removed the small delays that occur because of this, [with gaps] means that I just took the approximate frequency including these delays.
The next update of SMPSPlay and DEPlay with feature perfect DAC rates. (For SMPSPlay they're adjustable via ini-files.)
It's something I couldn't just get right, so I decided to do some research.
I startet with Oerg866's SMPS Player, which uses jman2050's DAC driver:
At first I made an SMPS file that plays a few DAC sounds and made each sound play the same sample, but with different DAC rates.
Then I used MESS to make a VGM of it. (MESS because MAME's timing system is extremely accurate.)
After that I wrote a small tool in VB that reads that VGM and calculated the frequency of each sound.
Finally I made another small VB tool that recalculated the formula FreqHz = BaseVal / (RateBase + DACRate) for the DAC rates I logged. With this tool I tested values for RateBase until I found a perfect one. (I made it recalculate BaseVal with the tested frequency of rate 01 and RateBase.)
Then I did the same with plain Sonic 1, Sonic 2, and Barver Battle Saga (because I already had its pointers) for the Data East driver.
And here are my results:
(The columns are DACRate, logged DAC samples, length of the DAC sound in VGM ticks (44100 Hz), DAC samples per VGM sample, DAC frequency.)
jman2050's DAC driver --------------------- 01 8,238 11,940 1.45 30,426.784 02 8,238 13,275 1.61 27,366.915 03 8,238 14,600 1.77 24,883.274 04 8,238 15,937 1.93 22,795.746 05 8,238 17,268 2.10 21,038.673 06 8,238 18,602 2.26 19,529.932 07 8,238 19,938 2.42 18,221.276 08 8,238 21,265 2.58 17,084.213 0C 8,238 26,598 3.23 13,658.764 10 8,238 31,926 3.88 11,379.308 20 8,238 53,243 6.46 6,823.353 30 8,238 74,561 9.05 4,872.464 40 8,082 94,060 11.64 3,789.243 80 4,278 94,054 21.99 2,005.867 C0 2,908 94,020 32.33 1,363.995 FF 2,212 94,038 42.51 1,037.338 00 8,238 352,309 42.77 1,031.185 -> FreqHz = 272624 / (7.96 + DACRate) Calculating with (8 + prim) is still a good approximation. (DACSmpl/VGMSmpl variance is <0.2 for rates <= 80) Sonic 1 DAC driver ------------------ 01 8,236 15,517 1.88 23,407.076 02 8,236 16,846 2.05 21,560.465 03 8,236 18,190 2.21 19,967.433 04 8,236 19,530 2.37 18,597.419 05 8,236 20,866 2.53 17,406.671 06 8,236 22,209 2.70 16,354.073 07 8,236 23,550 2.86 15,422.828 08 8,236 24,882 3.02 14,597.203 0C 8,236 30,252 3.67 12,006.069 10 8,236 35,602 4.32 10,201.888 20 8,236 57,041 6.93 6,367.483 40 8,236 99,906 12.13 3,635.493 80 8,236 185,658 22.54 1,956.326 C0 5,710 188,159 32.95 1,338.288 FF 4,354 188,077 43.20 1,020.919 00 8,236 357,141 43.36 1,016.987 -> FreqHz = 271053 / (10.58 + DACRate) Sonic 2 DAC driver ------------------ [without gaps] 01 5,994 10,634 1.77 24,857.570 02 5,994 11,593 1.93 22,801.294 03 5,994 12,550 2.09 21,062.582 04 5,994 13,505 2.25 19,573.151 05 5,994 14,464 2.41 18,275.401 06 5,994 15,442 2.58 17,117.951 07 5,994 16,400 2.74 16,118.012 08 5,994 17,349 2.89 15,236.348 0C 5,994 21,209 3.54 12,463.360 10 5,994 25,016 4.17 10,566.653 20 5,994 40,424 6.74 6,539.071 40 5,994 71,112 11.86 3,717.170 80 4,384 96,853 22.09 1,996.163 C0 3,014 97,425 32.32 1,364.305 FF 2,312 98,042 42.41 1,039.954 00 5,994 255,585 42.64 1,034.237 -> FreqHz = 275173 / (10.07 + DACRate) [with gaps] 01 5,994 11,152 1.86 23,702.959 02 5,994 12,146 2.03 21,763.165 03 5,994 13,140 2.19 20,116.849 04 5,994 14,163 2.36 18,663.800 05 5,994 15,155 2.53 17,442.125 06 5,994 16,181 2.70 16,336.160 07 5,994 17,175 2.87 15,390.707 08 5,994 18,178 3.03 14,541.501 0C 5,994 22,193 3.70 11,910.756 10 5,994 26,203 4.37 10,087.982 20 5,994 42,327 7.06 6,245.078 40 5,994 74,027 12.35 3,570.797 80 4,384 100,639 22.96 1,921.068 C0 3,014 100,638 33.39 1,320.748 FF 2,312 99,898 43.21 1,020.633 00 5,994 259,097 43.23 1,020.218 -> FreqHz = 265473 / (10.20 + DACRate) Data East DAC driver -------------------- 01 5,309 14,714 2.77 15,911.846 02 5,309 15,768 2.97 14,848.231 03 5,309 16,817 3.17 13,922.037 04 5,309 17,866 3.37 13,104.607 05 5,309 18,906 3.56 12,383.735 06 5,309 19,951 3.76 11,735.096 07 5,309 21,006 3.96 11,145.716 08 5,309 22,077 4.16 10,605.014 0C 5,309 26,261 4.95 8,915.384 10 5,309 30,457 5.74 7,687.129 20 5,309 47,284 8.91 4,951.504 40 5,309 80,941 15.25 2,892.562 80 5,309 148,154 27.91 1,580.294 C0 5,309 215,537 40.60 1,086.249 FF 5,309 281,543 53.03 831.585 00 5,309 282,774 53.26 827.965 -> FreqHz = 222766 / (13 + prim)
All formulas are accurate enough that the difference between tested and recauculated (DAC samples per VGM sample) is <= 0.2 for all rates. (except for Sonic 2 with gaps)
The Sonic 2 driver does all work on the Z80, so it needs to interrupt the DAC stream every frame to do update the music engine. [without gaps] means, that I removed the small delays that occur because of this, [with gaps] means that I just took the approximate frequency including these delays.
The next update of SMPSPlay and DEPlay with feature perfect DAC rates. (For SMPSPlay they're adjustable via ini-files.)

