It is currently Sun Oct 22, 2017 5:56 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 35 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Sun Nov 04, 2012 12:02 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
koitsu wrote:
The audio remains "smooth" for me (Windows XP Pro SP3), the only time I can get it to hiccup is when using GUI features or when it loses/regains focus.

No offense intended in the least by this statement, but I can hear and detect all *sorts* of issues in this emulator, some relating to sound emulation, others relating to simple usage -- including some audio issues in Megaman 2 (I can hear 3 consistent problems there). I also got the emulator to flat out crash (full application crash) when loading a common/popular ROM (i.e. not some crazy homebrew or Chinese game).

Also, one of the sound issues I've heard/detected pertains to overall playback rate being at the wrong base frequency. It's quite obvious that you're correlating the "base frequency" rate of the NES audio system, somehow, with the actual frequency/sample rate of a soundcard. I can tell because if I drop from 96000Hz to 48000Hz, the actual "base frequency" of the audio drops, and then the emulator craps itself with sound buffer overflows. :-) However, even at 96000Hz, the base frequency for the NES audio in general is still wrong (doesn't require a good ear either) -- it's way too high. Go load up a Megaman 2 NSF in an NSF player (Nestopia, NSFplug, etc.) and compare. :-)

I should warn you about correlating those two things, especially if the design is "use the highest frequency the soundcard advertises": many soundcards -- including built-in audio ICs as well as physical HBAs and even USB DACs -- will claim high rates but then behave oddly when those rates are used. I remember emulator authors 10 years ago talking about how on some cheap sound cards which advertised 48000Hz, for example, the audio would "freak out" (sound wrong, buffer oddities, some intermittent latency, etc.) yet 44100Hz worked fine. So I would be wary about this. You'd be better off picking something like 44100Hz, which is something everything should work with.

Where would you like feedback to be provided about these issues, or do you want folks to hold off until you're ready for bug reports? I'm cool either way.

Consider me impressed so far, and I'm very happy to see someone using SDL to boot. :-) Yay!


I'm glad you tested the lower sample rates, because I didn't think to. I know that sounds weird, but it's because they used to work perfectly. I was messing around a lot with the audio code a few months ago, and haven't touched the emulator since then until the last few days. I must have broken something along the way, I'll have a look and fix it. The way I modeled the sound generation, it's designed to be independent of sample rate. It modifies the current sample value for each channel at rates based on the CPU timing. That way, no matter what sample rate I'm outputting at I just need to mix the current values of the channel samples at any time I need. At least, it did work that way and I need to unbreak it. :)

And yes, I've seen a few crashes on certain ROMs too but I haven't dug deep to figure out why yet. Which ROM did you try specifically? My first guess is that a bad pointer is being set from faulty mapper code during a bankswitch. Something else I noticed was that the buffer can get overflow/underrun sometimes when the emu loses window focus. I changed the code so that the framerate is limited by the audio callback, and I guess that's what's causing it. I'll go back to the old timing method which should fix it.

Big thanks for giving it a try and pointing this stuff out, and I'll use your tip of defaulting to 44100. That's CD quality anyway. I think in the next day or so, I'll open up a new thread specifically for bug reports. I would love to iron out the wrinkles. I'll need to get a pretty big iron.

SDL rocks btw! It makes things easy if you want to go cross-platform. MoarNES could work fine in Linux, except that I'm using some Win32 specific APIs to attach a menubar to the SDL window and also some others to intercept window event callbacks and pick out the menu events before passing everything else back to SDL's original handler.


Top
 Profile  
 
PostPosted: Sun Nov 04, 2012 12:16 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
Mednafen wrote:
Using gettimeofday() for emulator timing purposes is probably a bad idea unless your code can handle time jumping backwards or forwards by a non-trivial amount without too much disruption.

clock_gettime() with CLOCK_MONOTONIC is a better choice on modern UN*Xes, though Linux has done somewhat weird and questionable things with it(and IIRC there used to be some Linux kernel bug(s) that would cause the time to jump backwards a small amount sometimes):

Code:
       CLOCK_MONOTONIC
              Clock  that  cannot  be  set  and  represents  monotonic  time since some unspecified starting point.  This clock is not
              affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the  clock),  but
              is affected by the incremental adjustments performed by adjtime(3) and NTP.

       CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
              Similar  to  CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments or
              the incremental adjustments performed by adjtime(3).


I've read something about that before too. I used to use clock_gettime() in my PC emulator when compiling for Linux, but I changed it to gettimeofday() when I found out OS X did not support clock_gettime() and I wanted it to work on that too. I actually have had no problems whatsoever with jitter, it seems accurate on a huge variety of machines that have been tested from 486s to eight-core bulldozers to embedded ARM (SheevaPlug and RasPi) and it all seems good so far. No bug reports from anybody else about it either, so I trust it enough.

Maybe it does jump backwards sometimes and I just don't know, but The overall timing must still be pretty good, because everything is nice and smooth including the Adlib, Sound Blaster, and PC speaker emulation which needs to be fairly precise.


Top
 Profile  
 
PostPosted: Sun Nov 04, 2012 1:52 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
I just went back and used a version of MoarNES from February, and it seems to be a lot more accurate in general. I think I'm going to go back to that old codebase and re-apply a few minor bugfixes I'd otherwise made since then and then replace its audio buffering code with the new stuff. I'll post it tomorrow. And yes, all of the sample rate stuff works right in that old one and the frequency sounds correct. :)

Hmm, I'll need to stick the AVI recording code into it too. Easy enough though.


Top
 Profile  
 
PostPosted: Sun Nov 04, 2012 12:10 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
miker00lz wrote:
I'll use your tip of defaulting to 44100. That's CD quality anyway.

It might be audibly worse if your sound synthesis has aliasing. At a higher rate, you effectively offload some of the filtering to the OS/sound card/human ears. The title music in Kid Icarus stresses filtering.


Top
 Profile  
 
PostPosted: Sun Nov 04, 2012 12:49 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
I'll let you work on the audio stuff first then I can test going forward and report back on that. :-) The only reason I tried different sample rates is because the base frequency sounded wrong even at the default of 96000Hz -- meaning everything still sounded too high pitched (octave-wise). I tried lower frequencies and was like "oh nice, now the octave decreases.... and buffer underrun, whee!!!" Haha. :-) I'm happy to help you test whatever is needed.

Other things / details I experienced:

1. Joypad input is still honoured even if the application has lost focus
2. Application focus -- emulator still runs in the background even when lost focus, except the music. This is a little strange to say the least. I'm guessing it's the root cause of the above item too
3. Emulator crash -- tried to load Blaster Master.nes (can send ROM if need be), so your guess that it's code relating to mappers is almost certainly spot on
4. Emulator saves last X/Y coordinates of the window when you quit. But upon re-launching the emulator, the emulator appears briefly in the upper left of the desktop (certainly positioned by Windows), then obviously moves itself to the saved X/Y coordinates. Emulator shouldn't appear in the upper left at all.
5. Please do away with the "Do you wish to quit?" dialog -- annoying. Else if it's preferred, make it a toggleable option.
6. Input configuration (joypad) -- please make this a native Windows configuration thing, and not something done within the emulator the way it is. Look at how Nestopia does it (meaning the style/model) -- it's easily the best style/model I've seen.
7. When a ROM isn't loaded, File -> ROM information... should be greyed out; thus there's no point to the Dialog() of "No ROM is currently loaded".
8. Same goes for "Close ROM" -- if a ROM isn't loaded, Close ROM should be greyed out.
9. Emulation -> CPU needs segregation between a hard reset (power-cycle) and soft reset (hitting reset button on NES / jumping to RESET vector). This is very important for games like Zanac, where if you soft reset the game 13 times, you get a special menu.
10. Joypad input -- this one is really hard to explain from a UI perspective. Basically with my joypad (it's a Playstation->USB adapter), your emulator requires me to press the "Analog" button on my PS2 controller before I can use the digital pad. I've seen this before in other emulators and it's shameful behaviour. In Nestopia, with "Analog" off, I see "(joy 0) -x" when pressing Left, while with "Analog" on I see "(joy 0) -p0x". So long story short I think you need to support some kind of other X/Y axis model that Windows or UHID provides, I just forget what it's called!
11. There have been many times where I'd loaded one game, played for a short bit (few seconds), then loaded another game and found its audio to be *completely* screwed up. It looks/sounds to me like you're not resetting your internal APU system state correctly or completely, i.e. there are some variables you need to reset/clear/reinitialise when loading a ROM image.
12. Please don't change the mouse cursor (invert its colour) when its X/Y coordinate is within the rendering/drawing surface. Maybe SDL is doing this, in which case I'll live with it. Moral: the less crap you mess with the better off you'll be. :-)

I'm intentionally leaving out all the audio anomalies I hear (they're obviously issues with the emulation, and that's totally okay! Work in progress! :-) ), but I have lots of games that sound quite wrong in many ways, sans one game:

About Megaman 2, since you stated it sounds pretty much perfect to you:

When firing Megaman's gun, there is what sounds like a bass-y "fart" noise at the end of the effect. You don't have to have an amazing ear to hear it, but I noticed it immediately. It's clearest on Air Man's level. I hear something similar when picking Normal/Difficult from the main menu, as Megaman flies off into the stratosphere, and when selecting a level.


Top
 Profile  
 
PostPosted: Sun Nov 04, 2012 12:57 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19115
Location: NE Indiana, USA (NTSC)
I think extra digital axes are called "hats" for some reason, possibly because the D-pads for controlling point of view on some flight sim sticks resemble traditional Chinese conical straw hats.


Top
 Profile  
 
PostPosted: Mon Nov 05, 2012 11:02 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
tepples wrote:
I think extra digital axes are called "hats" for some reason, possibly because the D-pads for controlling point of view on some flight sim sticks resemble traditional Chinese conical straw hats.


Thanks tepples, that's the term I was looking for. I also found it amusing that this industry term has "slanderous origins", heh. :-)


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 1:50 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
koitsu wrote:
I'll let you work on the audio stuff first then I can test going forward and report back on that. :-) The only reason I tried different sample rates is because the base frequency sounded wrong even at the default of 96000Hz -- meaning everything still sounded too high pitched (octave-wise). I tried lower frequencies and was like "oh nice, now the octave decreases.... and buffer underrun, whee!!!" Haha. :-) I'm happy to help you test whatever is needed.

Other things / details I experienced:

1. Joypad input is still honoured even if the application has lost focus
2. Application focus -- emulator still runs in the background even when lost focus, except the music. This is a little strange to say the least. I'm guessing it's the root cause of the above item too
3. Emulator crash -- tried to load Blaster Master.nes (can send ROM if need be), so your guess that it's code relating to mappers is almost certainly spot on
4. Emulator saves last X/Y coordinates of the window when you quit. But upon re-launching the emulator, the emulator appears briefly in the upper left of the desktop (certainly positioned by Windows), then obviously moves itself to the saved X/Y coordinates. Emulator shouldn't appear in the upper left at all.
5. Please do away with the "Do you wish to quit?" dialog -- annoying. Else if it's preferred, make it a toggleable option.
6. Input configuration (joypad) -- please make this a native Windows configuration thing, and not something done within the emulator the way it is. Look at how Nestopia does it (meaning the style/model) -- it's easily the best style/model I've seen.
7. When a ROM isn't loaded, File -> ROM information... should be greyed out; thus there's no point to the Dialog() of "No ROM is currently loaded".
8. Same goes for "Close ROM" -- if a ROM isn't loaded, Close ROM should be greyed out.
9. Emulation -> CPU needs segregation between a hard reset (power-cycle) and soft reset (hitting reset button on NES / jumping to RESET vector). This is very important for games like Zanac, where if you soft reset the game 13 times, you get a special menu.
10. Joypad input -- this one is really hard to explain from a UI perspective. Basically with my joypad (it's a Playstation->USB adapter), your emulator requires me to press the "Analog" button on my PS2 controller before I can use the digital pad. I've seen this before in other emulators and it's shameful behaviour. In Nestopia, with "Analog" off, I see "(joy 0) -x" when pressing Left, while with "Analog" on I see "(joy 0) -p0x". So long story short I think you need to support some kind of other X/Y axis model that Windows or UHID provides, I just forget what it's called!
11. There have been many times where I'd loaded one game, played for a short bit (few seconds), then loaded another game and found its audio to be *completely* screwed up. It looks/sounds to me like you're not resetting your internal APU system state correctly or completely, i.e. there are some variables you need to reset/clear/reinitialise when loading a ROM image.
12. Please don't change the mouse cursor (invert its colour) when its X/Y coordinate is within the rendering/drawing surface. Maybe SDL is doing this, in which case I'll live with it. Moral: the less crap you mess with the better off you'll be. :-)

I'm intentionally leaving out all the audio anomalies I hear (they're obviously issues with the emulation, and that's totally okay! Work in progress! :-) ), but I have lots of games that sound quite wrong in many ways, sans one game:

About Megaman 2, since you stated it sounds pretty much perfect to you:

When firing Megaman's gun, there is what sounds like a bass-y "fart" noise at the end of the effect. You don't have to have an amazing ear to hear it, but I noticed it immediately. It's clearest on Air Man's level. I hear something similar when picking Normal/Difficult from the main menu, as Megaman flies off into the stratosphere, and when selecting a level.


Yeah, you're right I can hear the fart noise. I've noticed it before, but haven't taken a good look yet. The audio stuff has been tough for me, this is the first time I wrote a serious software model to emulate a sound chip. You should have heard my first attempt, the current code sounds amazing compared to what it used to be.

That is a lot of issues you've got listed. Some I was aware of, others not. Blaster Master works here, btw. It plays well too. Maybe you have a slightly different version. I agree about the joystick config too, but that is very low in my priority list right now. I thought it was a decent enough makeshift way to config the controls for the time being. I've never designed and used an actual Windows form in C before, so that's why I'm putting that off. I'll tackle it once the emulator is more accurate, that's the important thing.

BTW, the inverted mouse cursor is an SDL thing. I'm sure there's a way to stop it. Maybe not directly with an SDL function, but I can always come up with some sort of hack to get around it. After all, the menubar on the SDL form is a hack. If you're resourceful enough with the Win32 API, basically anything can be done.

The sound disappearing is an XP+SDL quirk, btw. I have an old Pentium 1 MMX running XP, and the same thing happens there. It keeps playing here on Windows 7. I'm going to just force the emu to pause on losing focus anyway. That's actually caused me to get killed in games a handful of times if another window decides to pop up, or i accidentally hit the Windows key. :)

I'm doing a bit more work on the code. I didn't get enough time to work on it yet, so tomorrow I'll definitely come back and upload with some fixes. I may or may not need tips with some of the audio bugs, not sure yet. Damn NES sound hardware is so quirky.


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 2:10 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3944
When in doubt, copy-paste from Blargg's APU. Or at least copy the algorithms for the frame sequencer. Don't forget that part that mutes sound depending on current period and sweep settings (regardless of whether sweep is actually used or not).

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 5:24 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I skimmed your source and the first thing I notice is that you've got multiple threads without any locks on the shared variables. For example, these two run concurrently, the first from the emulator and the second from the audio callback:

Code:
int32_t bufferpos = 0, buffersync = 0, audiosync = 0;

void buffersampleAPU() {
   if (bufferpos < 16384) buf[bufferpos] = mixeroutAPU();
      else draw_persistent("[DEBUG] Audio buffer overflow");
   if (dorecord && (avibufptr < 16384)) avibuf[avibufptr++] = buf[bufferpos];
   bufferpos++;
}

void rebufferAPU(void *udata, uint8_t *stream, int16_t len) {
   if (bufferpos < (int32_t)len) {
      memset(stream, 128, len);
   } else {
      memcpy(stream, &buf[0], len);
      memmove(&buf[0], &buf[len], 16384 - len);
      bufferpos -= len;
      if (bufferpos < 0) {
         bufferpos = 0;
         draw_persistent("[DEBUG] Audio buffer underrun!");
      }
   }
   if (bufferpos < fastthreshold) sampleticks = fastticks;
      else if (bufferpos > slowthreshold) sampleticks = slowticks;
         else sampleticks = normalticks;
   donextframe = true;
}


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 7:15 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2963
Location: Tampere, Finland
I tried STREEMERZ on your emulator, the PPU emulation seems OK, but the sound was completely broken (it was good for humor though — and I say that with absolutely no offense intended).

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Tue Nov 06, 2012 10:19 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
thefox wrote:
I tried STREEMERZ on your emulator, the PPU emulation seems OK, but the sound was completely broken (it was good for humor though — and I say that with absolutely no offense intended).


Heh, yeah on some games the audio is just plain BAD! For most games it's reasonably accurate-ish. I just tried Streemerz in it too, btw. It's a good game!


Top
 Profile  
 
PostPosted: Thu Nov 08, 2012 3:18 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
blargg wrote:
I skimmed your source and the first thing I notice is that you've got multiple threads without any locks on the shared variables. For example, these two run concurrently, the first from the emulator and the second from the audio callback:

Code:
int32_t bufferpos = 0, buffersync = 0, audiosync = 0;

void buffersampleAPU() {
   if (bufferpos < 16384) buf[bufferpos] = mixeroutAPU();
      else draw_persistent("[DEBUG] Audio buffer overflow");
   if (dorecord && (avibufptr < 16384)) avibuf[avibufptr++] = buf[bufferpos];
   bufferpos++;
}

void rebufferAPU(void *udata, uint8_t *stream, int16_t len) {
   if (bufferpos < (int32_t)len) {
      memset(stream, 128, len);
   } else {
      memcpy(stream, &buf[0], len);
      memmove(&buf[0], &buf[len], 16384 - len);
      bufferpos -= len;
      if (bufferpos < 0) {
         bufferpos = 0;
         draw_persistent("[DEBUG] Audio buffer underrun!");
      }
   }
   if (bufferpos < fastthreshold) sampleticks = fastticks;
      else if (bufferpos > slowthreshold) sampleticks = slowticks;
         else sampleticks = normalticks;
   donextframe = true;
}


I have no idea how I missed your post last time I looked at this thread, but I did. That's a good point, i forgot the SDL callback happens in a different thread! I will fix this. I also think I should possibly look at using a ring buffer instead of memmove which has occured to me before but it happens infrequently enough that I wasn't concerned, and modern CPUs are obscenely fast. Even a 486 would do a memmove like that virtually instantly. Plus the move method is slightly more straightforward to look at and I was just trying to get it working at the time.


Top
 Profile  
 
PostPosted: Thu Nov 08, 2012 3:26 am 
Offline
User avatar

Joined: Thu Sep 23, 2010 7:28 pm
Posts: 232
Another thing that concerns me is that (at least the official ops, and I THINK the unofficial ops) my CPU instruction emulation is totally accurate, I am starting to think some of my timings may be off. I think the base CPU tick array is fine, but I might be not adjusting properly for certain jumps or other quirks, or maybe the way I'm handling the throttling to a certain number of ticks is flawed. Most games are fine, but the ones that are very sensitive to timing like Battletoads are often very screwed up.

I'm also definitely screwing something up with mapper 4. Have a look at SMB 3 in it! It's definitely playable, but there are issues when the screen scrolls vertically with the status bar being unstable among a few other problems. Another problem is SMB 3 is not mapper 4 related, but it's in my sprite handling. The stuff that comes out of "?" blocks shows in front of the block. My old, old codebase for the emulator (which was totally scrapped when I did a rewrite) handled the quirk properly. I need to figure out what I broke.


Top
 Profile  
 
PostPosted: Thu Nov 08, 2012 5:50 am 
Offline

Joined: Thu Nov 08, 2012 5:42 am
Posts: 1
miker00lz wrote:
Another problem is SMB 3 is not mapper 4 related, but it's in my sprite handling. The stuff that comes out of "?" blocks shows in front of the block. My old, old codebase for the emulator (which was totally scrapped when I did a rewrite) handled the quirk properly. I need to figure out what I broke.


Sounds like sprite priority isn't being handled correctly, these should help:

http://wiki.nesdev.com/w/index.php/PPU_sprite_priority
viewtopic.php?p=35452


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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