It is currently Sun Oct 21, 2018 3:58 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Mon Jul 23, 2018 12:57 am 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 412
rainwarrior wrote:
It's also oversampling for the output device.

No. Oversampling is when you sample a signal at a higher rate than the signal requires, not whatever your desired output is. To quote Wikipedia:
Quote:
In signal processing, oversampling is the process of sampling a signal with a sampling frequency significantly higher than the Nyquist rate. [...] The Nyquist rate is defined as twice the highest frequency component in the signal.
The Nyquist rate of the NES's audio is also, surprise surprise, its sample rate. The fact that it contains frequencies all the way up to half that rate is exactly why a resampler is needed.

But you're right, arguing semantics isn't helpful. I just don't want people to hear "oversampled" and think it's either a) something unnecessary that the NES itself doesn't do, or b) some kind of enhancement that makes your implementation better than other emulators (or actual hardware) that don't "oversample".

rainwarrior wrote:
Actually, to give you an idea why this affects performance so much for NSFPlay, how often it has to jump back and forth between CPU emulation and generating samples really adds a lot of overhead, and as a side effect negatively affects code caching / branch prediction / etc. at the same time. One of my planned ideas for performance improvement will be to institute the concept of CPU<->audio sync points so it can operate on longer buffers at a time, but that's going to be a big overhaul of the how original code worked. I suspect eventually, the idea of needing to undersample the NES might even be able to disappear, but for now it's deeply rooted in how it works. (If you look at other old NSF players, like NotSoFatso, this was pretty commonly done.)

Yep, repeat does that too. One cycle at a time. One word: ouch.

That's why I stopped working on it, in favour of a VGM player that uses logs and batching to run hundreds or thousands of cycles of each channel before moving onto the next. Once I get around to re-implementing the NES audio chips, I'll rip out my NES CPU emulator, make it spit out a write log, and let the audio emulation run in batches as large as it likes. But that's a ways off yet.

rainwarrior wrote:
As for integer vs float... yeah I mean we have good vector hardware for floats these days. I'm not sure if NSFPlay will ever make it to float, but it's something that could be done in theory at least. If this were a starting-from-scratch situation it would be a lot easier to write something from the beginning that would be easier to switch to one or the other with a #define. (...maybe for NSFPlay 3.)

Would it be helpful to anyone if I put my resampler code up somewhere? It needs a good cleanup, but I feel obliged to put my money (or rather code) where my mouth is, so to speak.


Top
 Profile  
 
PostPosted: Mon Jul 23, 2018 7:56 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20679
Location: NE Indiana, USA (NTSC)
Rahsennor wrote:
Once I get around to re-implementing the NES audio chips, I'll rip out my NES CPU emulator, make it spit out a write log, and let the audio emulation run in batches as large as it likes.

That's the paradigm I've been recommending for quite a while: one process emulates the CPU, outputting a stream of writes to another process that emulates the APU signal generation. I concede that parts of the APU would need to be emulated on the CPU side of the pipe as well, such as length counters if the program reads $4015.


Top
 Profile  
 
PostPosted: Thu Aug 02, 2018 3:20 am 
Offline

Joined: Sat Jun 01, 2013 11:55 am
Posts: 30
Location: Maine, U.S.A.
Accounting for all cycles and, when resampling, an accurate lowpass filter are needed for accurate results. Some box car interpolation can speed up the process, but the larger the ratio, the more inconsistent the attenuation. In my own tests, however, I've found that FIR alone can deliver messy results. So I've found a balance between the two.

Attached is 96 KHz, a box car of 4:1, followed by FIR (Blackman-Nuttall, 160 taps). The results are pretty clean, although the mixed channel portions differ from the hardware render (due to the nature of my MMC5 emulation).

Edit: corrected spelling of Nuttall. Also, the "messy results" I mentioned for FIR alone are probably because large fixed-point coefficient windows don't seem to respond well to raw rectangular pulses.

Update: it turns out the messy results I was getting was due to the limited precision used in interpolating the polyphase coefficients. The results are now cleaner. Now down to 139 taps using a Kaiser window.


Attachments:
File comment: No DC filter; Kaiser, beta=9.3
ultrasonic_tests-dc-kaiser9.7z [363.92 KiB]
Downloaded 14 times
File comment: No DC filter; Blackman-Nuttall
ultrasonic_tests-no dcf.7z [311.69 KiB]
Downloaded 47 times


Last edited by ap9 on Thu Sep 13, 2018 4:52 am, edited 4 times in total.
Top
 Profile  
 
PostPosted: Sun Aug 19, 2018 12:13 pm 
Offline

Joined: Sat Jun 01, 2013 11:55 am
Posts: 30
Location: Maine, U.S.A.
This is why you can't use boxcar alone (see attachment), as some emulators may do. While 2:1 is mathematically sound, no ratio provides 1:1 frequency response, and a pattern emerges the higher the ratio.


Attachments:
box car frequency response.png
box car frequency response.png [ 74.6 KiB | Viewed 783 times ]
Top
 Profile  
 
PostPosted: Sun Aug 19, 2018 1:36 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7676
Location: Seattle
A boxcar filter in time is a sinc in frequency, and vice versa. (Your graphs are "just" of abs(sinc(x)) on a semilog plot)

The only robust way to use a boxcar filter is to use it as a close-but-not-quite 1st order lowpass.


Top
 Profile  
 
PostPosted: Mon Aug 20, 2018 1:38 am 
Offline

Joined: Sat Jun 01, 2013 11:55 am
Posts: 30
Location: Maine, U.S.A.
Yes, boxcar is rectangular interpolation that it lines up with a rectangular sinc window. And likewise it has no side lobe suppression nor any flattening of the top in terms of frequency response. But it can make a good soft lowpass at 2:1 or an okay first order filter. Or in the case of use in my emulator, a reduction of computation time and memory requirements for storing samples (since the first stage uses the "WAVE[cycle>>boxcarshift]+=out" approach found in FCE Ultra).


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


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