About DPCM Samples

User avatar
CutterCross
Posts: 87
Joined: Sat Apr 28, 2018 9:42 pm

About DPCM Samples

Post by CutterCross » Sun Jul 01, 2018 2:33 am

I was just wondering, what EXACTLY are the issues that come up with using DPCM samples? Is it purely a ROM space issue, or are there other problems that arise in the engine itself when using them?
User avatar
TheNew8bitHeroes
Posts: 251
Joined: Fri Feb 16, 2018 9:24 pm
Location: Sarasota, FL
Contact:

Re: About DPCM Samples

Post by TheNew8bitHeroes » Sun Jul 01, 2018 2:44 pm

One of the problems with DPCM samples is that it they can corrupt controller reads. Trying to explain this, or how to fix it, or expect users to be able to dig into the scripts to fix it, or manage it correctly from the input...that's asking a lot. It's less work to just disable it, and then allow advanced users to add support.
User avatar
CutterCross
Posts: 87
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Sun Jul 01, 2018 3:17 pm

Oh I see, that explains why some games like Battletoads only opted for DPCM samples on the title screen and pause screen and not in actual gameplay (aside from the punching/kicking sfx). Though I'm curious on how games like Journey to Silius pulled off constantly playing samples in gameplay.

Of course, DPCM samples aren't necessary to make good music, but it's a fun challenge to see just how much you can get out of the stock 2A03 chip. I'll probably still do some experiments with samples when NESmaker releases, just to see what all the issues are for myself.
User avatar
Kasumi
Posts: 89
Joined: Fri Mar 09, 2018 11:13 pm

Re: About DPCM Samples

Post by Kasumi » Mon Jul 02, 2018 2:23 pm

The easy way:
Each frame:
1. Read each button's state and store them all temporary RAM
2. Read each button's state again and compare them to the value in temporary RAM
3. If the values don't match, use the buttons from last frame as this frame's buttons.
An equally easy way:
1. Read each button's state and store them all temporary RAM
2. Read each button's state again and compare them to the value in temporary RAM
3. If the values don't match, go back to 1. (This will get slightly more accurate input, but eats more CPU time. It can also effectively be made into an infinite loop by trolly hardware hooked up to the controller port.)
This topic describes a way (some ways?) to avoid most problems with exactly 3 reads: http://forums.nesdev.com/viewtopic.php?f=2&t=14197

But even ignoring the controller corruption, DPCM samples are inconvenient to use. They need to be in a very specific place in memory, and always present there. (One shouldn't bankswitch that area while a sample is playing.) For Mapper 30, where they need to be can't be bankswitched at all and is an area you'd want to put most of your engine code. Samples can end up competing for space with the NES Maker engine.
User avatar
TheNew8bitHeroes
Posts: 251
Joined: Fri Feb 16, 2018 9:24 pm
Location: Sarasota, FL
Contact:

Re: About DPCM Samples

Post by TheNew8bitHeroes » Mon Jul 02, 2018 4:21 pm

Kasumi - yeah. There are...lots of little issues. So it's much easier to say, "natively, it doesn't support a method for this...consider it an advanced feature" for anyone who wants to futz around at the code level. :-)
User avatar
CutterCross
Posts: 87
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Mon Jul 02, 2018 5:44 pm

Kasumi wrote:
Mon Jul 02, 2018 2:23 pm
The easy way:
Each frame:
1. Read each button's state and store them all temporary RAM
2. Read each button's state again and compare them to the value in temporary RAM
3. If the values don't match, use the buttons from last frame as this frame's buttons.
An equally easy way:
1. Read each button's state and store them all temporary RAM
2. Read each button's state again and compare them to the value in temporary RAM
3. If the values don't match, go back to 1. (This will get slightly more accurate input, but eats more CPU time. It can also effectively be made into an infinite loop by trolly hardware hooked up to the controller port.)
This topic describes a way (some ways?) to avoid most problems with exactly 3 reads: http://forums.nesdev.com/viewtopic.php?f=2&t=14197

But even ignoring the controller corruption, DPCM samples are inconvenient to use. They need to be in a very specific place in memory, and always present there. (One shouldn't bankswitch that area while a sample is playing.) For Mapper 30, where they need to be can't be bankswitched at all and is an area you'd want to put most of your engine code. Samples can end up competing for space with the NES Maker engine.
Thanks for the info Kasumi!
User avatar
CutterCross
Posts: 87
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Mon Jul 02, 2018 9:13 pm

Oh, I also have another question regarding samples. Are inputs more easily corrupted when the DPCM channel is playing more samples?

Like, say the DPCM channel is always playing a sample at any given time (AKA the DPCM channel is always on, and is never turned off). In that scenario, would input data ALWAYS be corrupted and therefore be impossible to read inputs? Can input data only be read correctly during a gap when a sample ISN'T playing?
User avatar
Kasumi
Posts: 89
Joined: Fri Mar 09, 2018 11:13 pm

Re: About DPCM Samples

Post by Kasumi » Tue Jul 03, 2018 2:19 am

CutterCross - If a sample is playing at all, input corruption is always possible. But it's not specifically playing the sample that causes the corruption. Playback only relies on the thing that causes the corruption.

If you're familiar with streaming services like youtube: A portion of the video loads. When you've watched most of the portion that loaded, more of the video is sent to you. And when you've watched most of that, more of the video is sent to you.

Sample playback works similarly. A portion of the sample data is loaded into a buffer by the hardware to play back later. When that portion is done playing, the next portion of the sample data is loaded.

If the read the hardware does that loads more sample data into the buffer happens at exactly the same time as the software reads the "controller register", the value given to the software will be incorrect. (But "at exactly the same time" is very specific. It's basically a 50/50 shot whether the read will be wrong even if it's as close to the sample read as is possible for the CPU to be at that point in time.)

High quality samples mean the buffer needs to be filled more often which increases the likelihood of the two things happening at the same time. It's like how a 1080p 60FPS stereo video would request data more often than a 240p mono video on youtube.

So input data can be read correctly while a sample is playing, but not when the buffer is getting filled (well, even that has a 50/50 shot of no effect). Since the buffer is not getting filled all the time, input data won't always be corrupted when playing back samples.

Anyway, this is just information. I could probably just provide joypad code that's DPCM safe and you wouldn't have to worry about the specifics. It's a one time change.

I see the harder bit as where the sample data needs to be and the implications of that. The engine growing could get in the way of someone's samples that used to fit. A user's samples growing could crash into the engine. So it's an "over time" change rather than a "one time" change.
User avatar
CutterCross
Posts: 87
Joined: Sat Apr 28, 2018 9:42 pm

Re: About DPCM Samples

Post by CutterCross » Tue Jul 03, 2018 2:45 am

Kasumi wrote:
Tue Jul 03, 2018 2:19 am
CutterCross - If a sample is playing at all, input corruption is always possible. But it's not specifically playing the sample that causes the corruption. Playback only relies on the thing that causes the corruption.

If you're familiar with streaming services like youtube: A portion of the video loads. When you've watched most of the portion that loaded, more of the video is sent to you. And when you've watched most of that, more of the video is sent to you.

Sample playback works similarly. A portion of the sample data is loaded into a buffer by the hardware to play back later. When that portion is done playing, the next portion of the sample data is loaded.

If the read the hardware does that loads more sample data into the buffer happens at exactly the same time as the software reads the "controller register", the value given to the software will be incorrect. (But "at exactly the same time" is very specific. It's basically a 50/50 shot whether the read will be wrong even if it's as close to the sample read as is possible for the CPU to be at that point in time.)

High quality samples mean the buffer needs to be filled more often which increases the likelihood of the two things happening at the same time. It's like how a 1080p 60FPS stereo video would request data more often than a 240p mono video on youtube.

So input data can be read correctly while a sample is playing, but not when the buffer is getting filled (well, even that has a 50/50 shot of no effect). Since the buffer is not getting filled all the time, input data won't always be corrupted when playing back samples.

Anyway, this is just information. I could probably just provide joypad code that's DPCM safe and you wouldn't have to worry about the specifics. It's a one time change.

I see the harder bit as where the sample data needs to be and the implications of that. The engine growing could get in the way of someone's samples that used to fit. A user's samples growing could crash into the engine. So it's an "over time" change rather than a "one time" change.
Okay, that explains a lot! Thanks!

So, what if I had a very small sample that constantly loops to make the sound last longer? Does the buffer need to constantly refill the same sample data over and over again, or is it a one-time thing at the start of sample playback?

I guess another question I'm asking is, how much sample data can the buffer hold at one time?
User avatar
Mihoshi20
Posts: 273
Joined: Tue Mar 06, 2018 11:47 pm

Re: About DPCM Samples

Post by Mihoshi20 » Tue Jul 03, 2018 3:26 am

There and interesting forum thread I stumbled across on NESDEV titled "DPCM generates extra $4016 read pulse" that talks about DPCM and it's relation to the controller inputs you might find interesting. http://forums.nesdev.com/viewtopic.php?t=4116

There's also this little nugget of info on the NESDEV wiki. "DPCM Safety using Repeated Reads: If your code is intended to be used with APU DMC playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, Super Mario Bros. 3 reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over. Because repeated rereads can take a long time, another way is to just use the previous frame's button press data if the results differ: "

I think the disabling DPCM capabilities for the engine and letting advanced users deal with it was the overall right choice given the tool's market and scope as nice as it would be to have the feature and once the tool is release to the public, a clever user may work the functionality back in that doesn't cause issues with controller input and release release the code for others to use.
Post Reply