This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Advantage of virtual sound registers

Advantage of virtual sound registers
by on (#38691)
These days I'm working on the famitracker sound driver so I can use it in my future game. People have mentioned that they want virtual registers since it would make their job easier.

I'm sure I could convert the sound driver to have virtual registers. It would require some effort, increase the memory footprint (which is already 235 bytes) but right now I cannot get the advantage of having those. In the current built I'm working on, you can specify the location of the music data and specify which channel you want to disable, which I think it quite enough for making a game.

The way is working is before asking the sound driver for the next frame in the music, you disable the channel you want to play sound fx, play your sound fx then request the next music frame to be played. I never have to worry what the sound driver should do, just disable the right channel and re-activate it when I don't need it anymore.

So, if I have the virtual registers, I have to worry more on how the music should be played. Why should I worry about that when the sound driver is taking care of that job? Why would I want to make my life harder?

This is how I feel right now about the virtual registers: it may had an extra layer of flexibility but increase the job to do and it complexity.

Any thought on the subject will be greatly appreciated. Right now I don't really need that functionality but if it could benefit everybody then I don't mind to do it.

The driver is now working fine with ca65 and nesasm. I may port it to other assembler later.

by on (#38701)
Write you own sound driver if you want to make sure it uses the right ressources you wan't to use, the amount of RAM you want it to use, etc...

I use my custom music engine for my game that has 32kb PRG so that it has less features than already existing ones, but I use it cleverly and I can get decent music with very little RAM and ROM using.

The day I'll write larger NES games or games for other platforms I'll be sure to use my own engine in all cases. Personally I love writing music engines, I find it very entertaining and rewarding. There is other things I don't like writing (who said AI for enemies ?) and noone come with pre-made engines for them :(

by on (#38713)
My music engine uses virtual registers and takes up 96 of it's own unique bytes in RAM. But it doesn't only use 96 bytes of RAM. It also uses Temp Variables and Temp Adds as well as jumping to a multiplication routine which returns the answer in other bytes in RAM.

If your engine can really do whatever it needs to do without using virtual registers, then great. That's the case, right? Also, virtual sound registers may not necessarily hold what's being played. They could hold the values of what was being played before it was updated. This might be handy to some people. When I tried just reading the real registers, the engine didn't work as I'd hoped. It actually worked differently in different emulators. So I ditched that and just went with virtual. Then it worked in every emulator I tested.

I just found that in my case, they helped me. If they don't for you, there's no reason that you need to have them.

by on (#38739)
Bregalad wrote:
Write you own sound driver if you want to make sure it uses the right ressources you wan't to use, the amount of RAM you want it to use, etc...


Of course someday I would love to write my own sound engine. I like to thinker with low level stuff. But right now I want to be able to make a game asap. With this sound driver and the tracker, this will be a huge time saver. Just writing a tracker+sound driver is quite a demanding task.

My point is right now there is no easy, everybody can use, sound driver available. By hacking this sound driver and adding the extra functionality for games (dynamic address for data location + sound fx playing), people will be able to make music with the tracker and quickly insert it in their game. They won't need anymore to hack some nsf file to do this job.

I hope this will increase the amount of new nes demo/games made by beginner's nes developer. For me, it doesn't bring anything back, just the feeling that I helped a few new developers and I brought something interesting to the community.

Bregalad wrote:
The day I'll write larger NES games or games for other platforms I'll be sure to use my own engine in all cases. Personally I love writing music engines, I find it very entertaining and rewarding. There is other things I don't like writing (who said AI for enemies ?) and noone come with pre-made engines for them :(


Great that you like making sound engines. If you have time, I want you to teach me the basics on how to use the sound registers to make good sound effects ;) I'm sure it would contribute to many new programmers too.

For the AI... I think this is something that you don't have any choice to make yourself since it's not related to the hardware. But maybe some basic AI like terminator style or other could be made generic for the nes, who knows. I have to start to work on those soon.

Celius wrote:
If your engine can really do whatever it needs to do without using virtual registers, then great. That's the case, right?


At the moment, yes, you don't even need to know what the player does: you just tell the driver to not play sound on X channel and it will stop it. Then once you're finished, you just re-enable that channel. Very simple.

Now I must find a way to make good sound fx samples to make sure that the driver and my updated code is working 100% but this is where I have issues right now. I need to figure out how to time properly my soundfx. If I could find a sample of a few fx, that would already help me. I would learn a lot from that. I don't think there is any on the nesdev front page?

Celius wrote:
Also, virtual sound registers may not necessarily hold what's being played. They could hold the values of what was being played before it was updated. This might be handy to some people.


Since famitracker does have a lot of variable for pre-processing, I guess this information is already available if you know where to look for. The only problem is that the code was lightly documented since it was never planed to be used for game like I'm trying to do. But after a little bit of research, you could find it. So I guess the virtual registers are not necessary actually.

Compared to your engine with use only 96 byte, the famitracker one is bigger but there is one reason: it has to cover as many case as possible because of the tracker interface. And since it was never planned for games, I don't think the amount of memory used was an issue. There is good chance it could be optimized.

Good then once my tests are finished with proper sound fx samples then I can release the driver for everybody. I may port it to wla or other assembler, if some people wants it.

by on (#38744)
Banshaku wrote:
Now I must find a way to make good sound fx samples to make sure that the driver and my updated code is working 100% but this is where I have issues right now. I need to figure out how to time properly my soundfx. If I could find a sample of a few fx, that would already help me. I would learn a lot from that. I don't think there is any on the nesdev front page?


The way I got started with messing with sound effects was looking at the Munchie Attack source code, as it has the sound effects stored in .byte statements. That, combined with NESSOUND.txt and the APU stuff on the wiki, I got a better understanding for some things. It might help you out, too!

by on (#38754)
Roth wrote:
The way I got started with messing with sound effects was looking at the Munchie Attack source code, as it has the sound effects stored in .byte statements. That, combined with NESSOUND.txt and the APU stuff on the wiki, I got a better understanding for some things. It might help you out, too!


Thanks for the comment. I will go check Munchie Attack source code as soon as I can.

As for the wiki, I looked at it but there's a lot of tech words that I don't know the meaning yet, so I have to understand those before I can understand the complete idea ;)

by on (#38755)
hehe I had the same problem Banshaku, but it seemed that NESSOUND.txt helped me understand the concept of how certain things worked. I'm not sure how or why, but it just seemed to help things click. Anyhow, you're a smart dude it seems, so you should have no problems once you hunker down with it : )

by on (#38761)
Roth wrote:
hehe I had the same problem Banshaku, but it seemed that NESSOUND.txt helped me understand the concept of how certain things worked. I'm not sure how or why, but it just seemed to help things click. Anyhow, you're a smart dude it seems, so you should have no problems once you hunker down with it : )


Thanks to your post, after testing the sound fx you suggested me (from Munchie attack), I may have actually understood more about it than I thought. I was just doubting myself too much about it because of the strange error I had.

I tried to isolate the error and now that I have a sound that I know is working, I was able to troubleshoot it.

I was trying to play a sound fx every time a button was pressed. Because I was doing it that way, a button could be pressed more than 60 time a second, which is normal. So it had an impact on my test for sound fx because I don't have any proper joystick handler yet.

So it was launching the same sound many time, creating some buzz sound and when the button buffering was over, the sound couldn't play completely because there was an error in the time handling code..

By trying to play one sound every 2 seconds, without the use of the joystick button, the sound was actually working fine. Now I have a few things I want to confirm when restoring the APU status and it this part is working fine, then the sound driver update is now finished.

Thanks again for this sample, it helped me pinpointing my error :)

by on (#38766)
I find it more logical to have "virtual" registers that actually stores data that is relevant for the music engine (for example duty cycle, volume, etc...) and then another routine that combines them and place them into actual sound registers (for example $4000 registers have both duty cycle and volume information into it).
Copy the volume and duty cycle into another variable and then copy that variable on the register in not a necessary step.

by on (#38773)
Banshaku wrote:
As for the wiki, I looked at it but there's a lot of tech words that I don't know the meaning yet

Let us know which words you don't know so that I can go cite Wikipedia or Wiktionary.

Quote:
I was trying to play a sound fx every time a button was pressed. Because I was doing it that way, a button could be pressed more than 60 time a second, which is normal. So it had an impact on my test for sound fx because I don't have any proper joystick handler yet.

It appears your demo doesn't have any proper video handler either, as that will probably lock your sound handler to 60 (or 50) executions per second.

by on (#38815)
tepples wrote:
Let us know which words you don't know so that I can go cite Wikipedia or Wiktionary.


I don't think it's because I'm not english native (or it could be), it may be because I never saw those technical words yet. When I see words like duty, envelope, sequencer etc in that context, I don't know how it impact the pitch, length and/or factors of the sound. Once I learn their meaning, I guess it will make more sense.

tepples wrote:
It appears your demo doesn't have any proper video handler either, as that will probably lock your sound handler to 60 (or 50) executions per second.


Could you elaborate more on the subject? You got me interested and I would like to know more about it.

Right now, everything is done when an NMI is fired. This mean reading the joystick, asking the next music frame, playing a sound etc is processed there. This would lock everything at 60/50 executions per second like you mentioned.

For the sound driver, I used my current tests files which are very basic, it only show my current learning process of the nes hardware. So in it current state there is no real handler yet. In the samples that I will give with the final version of the sound driver, I will remove everything and just show to use it properly.

by on (#38821)
Duty Cycle: Ever played Dragon Warrior/Dragon Quest? The difference between the music in the castle and the throne room is a different duty cycle used for the square wave.

by on (#38823)
Dwedit wrote:
Duty Cycle: Ever played Dragon Warrior/Dragon Quest? The difference between the music in the castle and the throne room is a different duty cycle used for the square wave.


I do remember a little bit the music. I just tried it back in an emulator to see the difference. Thanks for pointing this one out.

It affect the sound, but not pitch. Or my usage or pitch is wrong. Now I will use the word duty for this type of impact on the sound but if, for example, someone didn't know what is the duty, how would you explain it with different words? This is the kind of explanation I would like to find. What I don't know is if those words are common or not.

Another example is you have a timer and a length counter. Both seems to relate to time but how, I'm not sure yet. I think I should study more the document and will be able to figure out that aspect.

by on (#38833)
Have you heard of "timbre"? It's the aspect of the sound that isn't loudness or pitch.

In a square wave, "duty cycle" is how much time the waveform spends high vs. low. This changes the timbre.

by on (#38845)
tepples wrote:
Have you heard of "timbre"? It's the aspect of the sound that isn't loudness or pitch.

In a square wave, "duty cycle" is how much time the waveform spends high vs. low. This changes the timbre.


Yes, I did heard of it since it a french word. So this is the "color" of the tone. Said that way I can visualize it.

By the way, I still want to hear more about the issue you mentioned regarding the sound lock at 60 executions per second. You hit my curiosity button :) We could aways discuss it in another thread is this one is not appropriate.

by on (#38846)
Banshaku wrote:
By the way, I still want to hear more about the issue you mentioned regarding the sound lock at 60 executions per second.

Most games run the sound code once every vertical blank, which occurs 50 times a second in France and the rest of Europe, and 50 times a second in New Zealand and Australia, but 60 times a second in North America and Japan. So if you wait for the vblank NMI, push your graphics updates, and then process the controllers and sound, it'll happen 50 or 60 times a second.

by on (#38892)
tepples wrote:
Most games run the sound code once every vertical blank, which occurs 50 times a second in France and the rest of Europe, and 50 times a second in New Zealand and Australia, but 60 times a second in North America and Japan. So if you wait for the vblank NMI, push your graphics updates, and then process the controllers and sound, it'll happen 50 or 60 times a second.


I was aware about the speed depending of the region, thanks for reminding me about it but this is not the answer I was expecting. My question may have been not clear I guess. Sorry, I will try to clarify.

From you comment, you seemed to imply something was wrong. You said:

tepples wrote:
It appears your demo doesn't have any proper video handler either, >>as that will probably lock your sound handler to 60 (or 50) executions per second.<<


If you look at the text between >><<, you seem to imply that since there is no video handler, this would probably lock the the sound at a specific speed and it could be an issue. This is how I understood your comment. I wanted to know why you mentioned this possible issue, if there is any.

by on (#38916)
Banshaku wrote:
If you look at the text between >><<, you seem to imply that since there is no video handler, this would probably lock the the sound at a specific speed and it could be an issue.

I meant that if you do have a video handler, it will lock your playback rate to something sensible, and such locking is good. But I see how it could have been misinterpreted.