|Page 1 of 1|
|Author:||Anes [ Sun Jan 23, 2005 7:50 pm ]|
|Post subject:||Apu Emulation|
well, after al the advices and help from you guys i made a simple thing to hear sounds. I think its a good starting point.
i check when the channel timer register is written, and take the 11 bit wavelenght and convert it to herz with the following formula:
hz = 1789772.5 / DIVIDER / WaveLenght
Where DIVIDER is 16 for square and 32 for Triangle (i guess), then thanks to Charles Petzold "FillBuffer" function expample form his "Programming Windows" Book, i convert "hz" to PCM format.
The result? sound.. but very poor. I know disch told me about a way of taking all the outputs to sample correctly: as APU does.
But i didnt understand you well disch, if you could explain it to me very "step-by-step" i will preciate it.
|Author:||Disch [ Sun Jan 23, 2005 8:11 pm ]|
Calculating to Hz is a bad idea. Since the APU revolves around cpu cycles... you just have to execute the cycles as they come.
To emulate a Square Wave channel... you'll need vars to track the following (my 'aka' is what I'll be referring to those vars as later):
- The 11-bit written wavelength value (aka nProgTimer)
- A counter to 'count down' that wavelength value (aka nProgCount)
- The current Duty cycle (2,4,8, or 12... representing 12.5%, 25%, 50%, and 75% duty cycles respectively) (aka nDutyCycle)
- A counter to track the steps through those duty cycles (aka nDutyCount)
You'll need to do the following for every 1 CPU cycle (assuming channel is active):
- if nProgCount is zero...
--- reload nProgCount with nProgTimer
--- increase nDutyCount by 1 (wrap at 15 ... 15->0)
- else, nProgCount is not zero...
--- decrease nProgCount by 1
the APU's output for this cycle is found by checking the following:
* if the channel is silenced by the Length Counter, or Sweep Unit --- output is 0
* else if nDutyCount is greater than or equal to nDutyCycle (in the 'negative' portion of the duty cycle) --- output is 0
* else, output is whatever the current Volume level is
now note... if using the simplest, low quality method of downsampling I mentioned earlier... you'll only be taking the output after every ~40.58 CPU cycles
|Author:||Anes [ Sun Jan 23, 2005 10:43 pm ]|
thanks disch, i will try implement that.
|Page 1 of 1||All times are UTC - 7 hours|
|Powered by phpBB® Forum Software © phpBB Group