Sound Emulation

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
Cloudy
Posts: 9
Joined: Wed Apr 22, 2009 12:47 am

Sound Emulation

Post by Cloudy » Fri Apr 24, 2009 12:54 am

Hi guys,

I am writing an emulator for learning purposes and have completed it with the exception of sound emulation. I am not writing a NES emulator yet but the console I am emulating sound is very very similar so im hoping you guys can give me a hand.

I have no knowledge of how sound emulation is intended to work and no knowledge of sound programming in general which is why im finding this very difficult. It is not so much the technical side Im having trouble with but how the compontents work together to produce sound.

Anyway I am going to emulate the two square waves first but need help understanding the logic behind how these work. This is my understanding, if you could fill in the blanks or correct any mistakes I have (there will be plenty) then that'd be great.

1. The programmerable timer is an 11 bit down counter which combines two sound registers together to get its value. This counts down at a set frequency which I update after every opcode emulation by the amount of cycles that opcode takes. When this reaches 0 then it reloads itself by combining the two registers again. Everything ok up to this point? Im also unsure what happens if the two sound registers which create the programmable timer are written to before the current timer has reached 0, does it start the count down process again or does it only change when the timer reaches 0 and reloads?

2. The duty cycle is a way of changing the output of the wave from positive to negative. Depending on the duty cycle wave this can give different ratios of positive to negative. If it is set to 50% then there will be the same amount of positive outputs as negative etc. This gives a value to count down whenever the programmable timer reaches 0. So using the 50% as an example it will count down from 4 to 0 (which means the programmable timer has reloaded 4 times) and at this point it changes its polarity and counts down from 4 again. This ok so far?

3. The length counter is a way of turning off the channel when the length counter reaches 0. Once again does the length counter decrement in value every time the programmable timer reaches 0? The length counter only takes affect if it is enabled.

4. Combining the programmable timer with the duty cycle generator will give a value of +1 or -1 this then gets multipled by the volume and added to the playback buffer. The volume is controlled by a volume envelope which starts at a set volume and gets increased or decreased by a value of 1 for a set amount of steps. Is this correct and at which point does the volume change its value, is it again tied into the programmable timer reaching 0?

I am aware that I have probably made a lot of mistakes so any help would be greatly appreciated.

Thanks

tepples
Posts: 22361
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Sound Emulation

Post by tepples » Fri Apr 24, 2009 4:35 am

Cloudy wrote:1. The programmerable timer is an 11 bit down counter which combines two sound registers together to get its value. This counts down at a set frequency which I update after every opcode emulation by the amount of cycles that opcode takes.
It finishes every 2 * (value + 1) cycles. For instance, writing 499 will cause it to finish every 1000 cycles.
Im also unsure what happens if the two sound registers which create the programmable timer are written to before the current timer has reached 0, does it start the count down process again or does it only change when the timer reaches 0 and reloads?
As I understand it, writes to the FREQLO registers ($4002 and $4006) take effect on the next reload, but writes to the FREQHI registers ($4003 and $4007) cause a click.
2. The duty cycle is a way of changing the output of the wave from positive to negative.
Actually positive to zero, and a high-pass filter on the NES's final output handles making it go negative.
Depending on the duty cycle wave this can give different ratios of positive to negative. If it is set to 50% then there will be the same amount of positive outputs as negative etc. This gives a value to count down whenever the programmable timer reaches 0. So using the 50% as an example it will count down from 4 to 0 (which means the programmable timer has reloaded 4 times) and at this point it changes its polarity and counts down from 4 again. This ok so far?
As I understand it, they all count up in (0..7) range and use the value as an index into what amounts to a look-up table.
3. The length counter is a way of turning off the channel when the length counter reaches 0. Once again does the length counter decrement in value every time the programmable timer reaches 0? The length counter only takes affect if it is enabled.
Length counter is related to the APU "frame" counter (60 or 48 Hz), not the pitch.

Cloudy
Posts: 9
Joined: Wed Apr 22, 2009 12:47 am

Post by Cloudy » Fri Apr 24, 2009 6:20 am

Thanks for the reply!

The emulator now plays sound, it isnt the correct sound but at least it is sound :D

I assume I dont need to do the volume envelope straight away to hear the correct sound because it is only volume.

The pitch (or frequency) seems very high on the tune it is playing but the rhythm seems about right. I dont think there is anything else I need to do in order to get the square waves functioning correctly. So far I have the following:

Programmable Timer, Length Counter, Unified Length Counter and duty cycle generator. Im still missing volume and frequency envelopes but I'll implement these when the tune sounds correct.

but writes to the FREQHI registers ($4003 and $4007) cause a click.
What do you mean by "click"?
Actually positive to zero, and a high-pass filter on the NES's final output handles making it go negative.
What difference would it make if I just outputted positive and negative without applying the filter?

User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 521
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Post by Jarhmander » Fri Apr 24, 2009 8:28 am

Cloudy wrote:

but writes to the FREQHI registers ($4003 and $4007) cause a click.
What do you mean by "click"?
As described here :http://nesdevwiki.org/wiki/APU_Pulse, a write to these register reset the sequencer, causing a phase reset. This is what he calls a 'click'. You may call it 'pop' too, that just depend of your sense of humor.
Cloudy wrote:
Actually positive to zero, and a high-pass filter on the NES's final output handles making it go negative.
What difference would it make if I just outputted positive and negative without applying the filter?
the difference is that the APU outputs only positive signal, not bipolar ones, and some channels (the triangle and DPCM channels) naturally output DC level when idle so the hi-pass filter simply block those DC levels while 'centring' the audio signal.

Post Reply