me again with a soundoutput question

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

me again with a soundoutput question

Post by Anes »

Disch give me a framework to work with sound, well i dont know why he mentions a "getsquare1out" func. that ruturns a value greater than a byte. I thought the value of the output is the 4 bit (depending of decay) of envolpe register.

Which is the output do i have to get? its my first time programming sound and pcm and i dont know very much. Can somebody help me?

Thanks in advance.
ANes
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Well I suppose you don't need a getsquare1out function... I was just showing the concept.

Anyway... at any given cycle, a square channel is outputting 0-F... which can be found by the following conditions:

- If the length counter is disabling the channel -- output is 0
- If the sweep unit is disabling the channel -- output is 0
- If the duty cycle is in "negative" state -- output is 0
- else, output is the current volume level (0-F)

So with the very simplest implimentation, you could check to see what the channel is outputting every ~40.58 cycles and output that to your sound buffer.


To give you a visual idea.... assuming the channel is active (length counter and sweep unit are allowing output).. assume the channel volume is set to A... and assume a 50% duty cycle... with $028 as the 11-bit written wavelength... and assuming a samplerate of 44100... your square output might look something like this:

A A A A A A A A 0 0 0 0 0 0 0 0 A A A A A A A A 0 0 0 0 0 0 0 0 ... etc

that constant on/off cycling is done by the duty cycle -- it being off at those times is what produces the Square shape of the waveform.
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

apu

Post by Anes »

so, it seems im not emulating it too bad. Im writing the channels envolope value to the sound buffer, if its "0" or the channel is silenced i write "128" (no sound), and if its not "0" i write the envelope.
Is that right?
ANes
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

He (Disch) works with unsigned samples, I would say the 'nostalgic side'. ;)
On my side, read - if the channel is disabled by any reason, the output is obviously zero; otherwise, it can be +Value or -Value.

There's 2 sample sizes: 8-bit and 16-bit (umm... yeah). If you choose the 8-bit form, then values are -128 up to +127; else, the 16-bit assumes -32768 up to +32767 (signed int). You're the judge - there's no right choice.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Re: apu

Post by Disch »

Anes wrote:so, it seems im not emulating it too bad. Im writing the channels envolope value to the sound buffer,
yes... but only under those conditions I listed. Writing all A's will produce silence... just like writing all 0's. The whole point is to have alternating positive output and zero... this produces the waveform. Without it you won't be playing anything.

if its "0" or the channel is silenced i write "128" (no sound), and if its not "0" i write the envelope.
Is that right?
Well... I'm giving you signed numbers (not unsigned, Fx3 ;) ). You need unsigned if you are outputting 8-bit sound in windows... so just XOR your output sample with 0x80 to make the conversion.

so if your output is 0... you'd write 0x80 to your sound buffer -- this would be the "center line" on an oscillator. And if you're outputting A... you'd write 0x8A to your sound buffer.
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

In other words:

For 8-bit output:

Code: Select all

sample = value ^ 0x80;
For 16-bit output:

Code: Select all

sample = value ^ 0x8000;
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

square wave

Post by Anes »

but, suppose i have sqrout func. that check if the channel is silencied, if silenced returns 080H, if its not ruturn Value XOR 080H.
So the func. can return 3 types: -silenced 80H, - not silenced XOR 80H and silenced again (silence that is not returned by a silence lencounter and negative value of duty cycle).

Havin this ruturns values does not deformate the wave?

I hope i could explain well..
ANes
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Don't do that. It'll make it harder to mix channels later

Keep everything signed -- ie: 0 = silenced, greater than zero = output.

Have your square out function return 0 if the channel is silenced... or 0-F if the channel is on (depending on the duty cycle and volume).

Before you output this sample to your audio buffer... you can convert it to unsigned by very simply doing:

sample ^= 0x80;

Do not put that $80 in the square out function of you'll probably just have to take it out later (like when you want to mix the other square's output with this one... or mix in the triangle and other channels)


Probably should look something like:

Code: Select all

sample = 0;
sample += Square1Out();

sample ^= 0x80;
WriteSampleToAudioBuffer( sample );
Square 1 out should NOT be returning these insane high values (alternating 0x80 and 0 would be painfully loud with 8-bit audio). Use the volume level of the channel as it is. If it's too quiet... multiply 'sample' by 2 or something before you output it to the buffer.

Your square 1 out should probably just be returning a value between 0 and F.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust »

As long as your overall audio level never exceeds 0x7F, you should be okay - otherwise, you will experience some wicked clipping as a result.

If you need to output a "centered" waveform, you should output 0 for silence and +/- VOL when the wave is playing. It may not perfectly represent the waveform coming out of a real NES, but it will sound almost exactly the same.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

thx

Post by Anes »

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

Post by tepples »

Quietust wrote:If you need to output a "centered" waveform, you should output 0 for silence and +/- VOL when the wave is playing. It may not perfectly represent the waveform coming out of a real NES, but it will sound almost exactly the same.
Not with the "Hello" demo that uses the square wave channels as a faux PCM register.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust »

I consider that to be an extreme case, extremely unlikely to be actually USED by anyone (since you can just use raw PCM for a much higher quality waveform).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply