It is currently Fri Dec 15, 2017 11:09 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Nov 28, 2004 7:00 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
I was on hold... but i decided to ask anyways...
Yes, I know the Blargg's page, but not much, only graphics and basic information. FCEUltra and VirtuaNES have their own way to generate an outstanding pAPU output.

Is there any algorithm or a more detailed information available for bandlimited synthesis? ;) Thanks in advance.

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 3:57 am 
A slow, but generally accurate, way would be to generate one sample per NES CPU cycle(effective rate would be about 1.78977272Mhz with NTSC), and resample it to 44.1KHz or whatever the output rate is.

If I were to reimplement the resampling code in FCE Ultra from scratch, I'd look into using an MMX or SSE based FIR filtering routine to resample the stream by an integral divisor(32 would be good) of the original rate, and then use libsamplerate http://www.mega-nerd.com/SRC/api.html to resample it to the output rate.

So, you would have:

1.789772 MHz MMX/SSE FIR filter-> 55,930.4 Hz libsamplerate-> 44,100Hz


Top
  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 3:59 am 
Oh, I forgot one thing. I'd use gmeteor to create the filter coefficients. Be warned that it can run very slowly.

http://gmeteor.sourceforge.net/


Top
  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 6:39 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
Thank you for the information... Quite interesting. :)

_________________
Zepper
RockNES developer


Last edited by Zepper on Sat Feb 27, 2010 6:57 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 11:52 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
The easiest way I've found to downsample is simple:

Accumulate the output of each channel every cycle and when you output a sample, divide that value by the number of cycles passed. It's not dreadfully slow, and produces a mighty-fine quality sound (although there are better methods)

For an example... every cycle the channel is clocked (this can be optimized by mutliplying Channel_Output by a value... I'll show sample code later):

OutputBuffer += Channel_Output;


When you output a sample:

SampleOut = OutputBuffer / CyclesPastSinceLastSample;
fTicksUntilNextSample += fTicksPerSample;

fTicksPerSample should be floating point and set to CPU_CLOCK_RATE / SAMPLE_RATE. On an NTSC system outputting at 44KHz, this will be roughly 40.58 (don't round too much). This means CyclesPastSinceLastSample will alternate between 40 and 41 as samples are generated.

This is the method I use in NotSo Fatso and I'd say it works quite well.

In case it's still unclear... here's some demo code to further clarify:

void DoSquareTicks(int ticks)
{
int mn;

while(ticks)
{
mn = min(nFreqCount, ticks);

ticks -= mn;
nFreqCount -= mn;

if(nDutyCount < nDutyCycle)
nSquareOutputBuffer += nVolume * mn; /*output volume if duty cycle is in positive section*/

if(nFreqCount <= 0)
{
nFreqCount = nFreqTimer.W + 1;
nDutyCount = (nDutyCount + 1) & 0x0F;
}
}
}


void RunAPU(int tick)
{
int mn;

while(tick)
{
mn = min( tick, ceil(fTicksUntilNextSample) );

fTicksUntilNextSample -= mn;
tick -= mn;

DoSquareTicks(mn);

nCyclesPassed += mn;

if(fTicksUntilNextSample <= 0)
{
fTicksUntilNextSample += fTicksPerSample;
OutputSample( nSquareOutputBuffer / nCyclesPassed );
nCyclesPassed = 0;
}
}
}



That code wont' work... but it'll give the general idea.

The method Blargg discusses in his doc (the one where you put transitions in a buffer, then run through the buffer later to generate samples) is likely faster and higher quality. It's kind of hard to understand though. I have yet to actually finish a player which impliments it.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 1:28 pm 
Offline
User avatar

Joined: Thu Nov 11, 2004 5:30 am
Posts: 121
Location: San Francisco, CA
Disch wrote:
The easiest way I've found to downsample is simple:

Accumulate the output of each channel every cycle and when you output a sample, divide that value by the number of cycles passed. It's not dreadfully slow, and produces a mighty-fine quality sound (although there are better methods)
[snip]


while the naive linear interpolation method you describe does produce generally acceptable results (it's what i used in my shitty nsf plugin way back in the day), it's important to note that it is exactly why shay presented his bandlimited technique - lerp creates aliasing, especially in the upper range of the nes frequencies.

_________________
...patience...


Top
 Profile  
 
 Post subject: :(
PostPosted: Mon Nov 29, 2004 3:43 pm 
Offline
User avatar

Joined: Wed Nov 17, 2004 12:34 pm
Posts: 41
My head hurts :(

I did it the "naive" way

Hey Disch, if you ever actually implement Blargg's buffering thing make sure you tell us if it was worth it :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 3:53 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1393
My emulator also does the same 'naive' downsampling, mainly because a proper FIR filter would be trying to consume CPU time that simply isn't available.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 4:50 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
WOOHOO!!! :lol:
What a nice day... hehehe ;)
It worked nicely. Thanks for the help!

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 5:38 pm 
Offline
User avatar

Joined: Thu Nov 11, 2004 5:30 am
Posts: 121
Location: San Francisco, CA
Quietust wrote:
My emulator also does the same 'naive' downsampling, mainly because a proper FIR filter would be trying to consume CPU time that simply isn't available.


as does mine. and i assume that's what most are doing. but that's why on all of them, you can hear the aliasing effects in the kid icarus intro and the solstice music. :)

_________________
...patience...


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 9:05 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
baisoku wrote:
but that's why on all of them, you can hear the aliasing effects in the kid icarus intro and the solstice music. :)


The reasoning the aliasing appears for Kid Icarus in NotSo is because I emulate the non-linear interdependency square output as layed out in blargg's doc (and he tells me that he noticed the same aliasing appearing from the real thing.. though I haven't personally tested this). When I have both channels outputting independent, linear output... I can't notice any audible aliasing.

Perhaps I could record a quick wav or something for a demo and see if you guys notice any?

But yes... I've gotten Blargg's methods working and the results were definatly worth it. Less CPU intensive since you don't have to run each channel seperately for each sample (you can run them all at once for a big chunk the size of your output buffer). A crisper sound, and allows for more nifty sound tricks and easier filter application.

It's definatly worth it. It's just somewhat weird to understand. I didn't understand it fully myself until I exchanged several e-mails with Blargg.


Top
 Profile  
 
 Post subject: :)
PostPosted: Tue Nov 30, 2004 12:10 pm 
Offline
User avatar

Joined: Wed Nov 17, 2004 12:34 pm
Posts: 41
Would you mind posting those emails somewhere Disch for those who may run into the same problems you did?


Top
 Profile  
 
 Post subject: Re: :)
PostPosted: Tue Nov 30, 2004 3:01 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
laughy wrote:
Would you mind posting those emails somewhere Disch for those who may run into the same problems you did?


Yay better, assemble a document. I'm sure it'll be much welcome.

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject: Re: :)
PostPosted: Tue Nov 30, 2004 7:18 pm 
Offline
User avatar

Joined: Wed Nov 17, 2004 12:34 pm
Posts: 41
Fx3 wrote:
laughy wrote:
Would you mind posting those emails somewhere Disch for those who may run into the same problems you did?


Yay better, assemble a document. I'm sure it'll be much welcome.


Hey you did a good job on RockNes - however my facepic is still better.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 20, 2004 5:11 am 
Offline

Joined: Mon Dec 20, 2004 4:51 am
Posts: 6
sllightly better then linear interpolation with out the over head of fir would be a weighed guassian with it's center at the center of the sample period I can't remember the coefficents, but there are some with power of two coefficents which of course eliminates the divide, if anyone cares, I'll post em. example


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Yahoo [Bot] and 13 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