It is currently Sat Dec 16, 2017 11:33 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Apu Emulation
PostPosted: Sun Jan 23, 2005 7:50 pm 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
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.

_________________
ANes


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 23, 2005 8:11 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
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


Top
 Profile  
 
 Post subject: apu
PostPosted: Sun Jan 23, 2005 10:43 pm 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
thanks disch, i will try implement that.

_________________
ANes


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: thefox and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group