Hey,
I decided to spend a little time this weekend putting together a VB sound generator, which attempts to be a cycle accurate VSU emulator. You give it an input file of register values and time delays, and it converts it to a wav file, and optionally outputs C code corresponding to the input sequence.
I’ve been wanting to do this for a long time… it just finally seemed like a good time to do it. There’s a lot of reasons for it, the main one being that it’s inconvenient to develop sounds by testing them on the VB to hear how they sound, and unfortunately Reality Boy isn’t very accurate. I’m hoping in the long term that it may be possible to optimize this and roll it into RB, though that’s not on my todo list yet.
What really started the project was wanting to know how the random noise generator worked (the manual specifies an LFSR, but it wasn’t clear on what’s actually output, and the tap locations, or notations, don’t really make sense). The easiest and most for sure way for me to figure this out was to make a long recording and pull out the bit sequence. I did this by writing a MATLAB script to detect the first edge in the wav file, then sample 1/2 sample past that, and every sample beyond that. From that I got the LFSR bit sequences (which repeated as expected every time π ).
I’m guessing there will be bugs and inaccuracies (I haven’t compared any of it with hardware yet, though it sounded good to my ear :-P).
I’m just posting the exe, example input file, and readme for now, though I’ll post the source with the next version… so try it out and give me some feedback π . I’d also like a GUI for this… as much as I dislike Visual Basic, this actually seems like the perfect application for that… so we’ll see. Of course if anyone else would like to do the GUI, that’d be great (but let me know so I don’t start one π ).
DogP
Attachments:
Wow, a great idea and superb execution! :thumpup:
Not only is it handy for VB game making, it can also be used to make sound effects for PC games, and such! (I definitely intend to try making some sounds for Flash games with it. π In fact, if I really get bored, I might even make a Flash port…)
I could probably make a (non-Visual Basic) front-end or GUI version, but I thought of another solution: make a WinAmp input plugin. It would allow instant previewing while debugging a sound and then the C code could be generated on the clipboard, or Notepad.exe could be used as an output window. You would even get Linux (and probably OSX) support for free that way, since XMMS comes with practically every distro.
Thanks for the comments… the GUI that I’m talking about would be for configuring the registers, rather than editing the input text file. You could move sliders around to make waveforms (or select predefined ones), use dropdowns to select registers and hit checkboxes to select their meanings (instead of just putting in the raw values). Then of course a preview button, which would run it through the process and play the wav file. The ability to step back and forth through the commands would be nice.
DogP
Well, that only sounds moderately more difficult than the RB front-end I worked on, and that wasn’t so bad.
Hmm… maybe David Tucker and I are the only ones who’ve seen my version of the front-end… I never got a reply when I sent it to him and it doesn’t look like he posted a new RB on his site. Maybe I’m the only one who has it! π
Well, I guess it won’t do any harm to post it here. Maybe someone can try it on Vista/7 and I can tweak it if necessary (although it was compiled with VS2008 instead of VC6, like the old one was, so it should work better). I fixed a few bugs and added the new command-line arguments (like netplay) as well as giving it a graphical face-lift.
EDIT: What’s the deal with the length restriction on attachment filenames? π It’s supposed to be “Reality Boy Front-end (Win32; EN).exe”. Maybe it’s the semicolon…
Also note that it’s a self-extracting archive including source, executable, and (HTML) help.
- This reply was modified 14 years, 11 months ago by RunnerPack.
- This reply was modified 14 years, 11 months ago by RunnerPack.
Yeah, GUIs in C++ aren’t too bad, but I just want something that I can put very little effort into making… but if you want to make it, that’s even less effort than doing it in VB π . Maybe I’ll mock up what I think the GUI should be like and post it here for comments and ideas. I probably haven’t used VB in about 10 years anyway, so who knows what I’d remember π .
DogP
Here’s a quick mockup of the GUI that I was thinking of. Basically, it’d allow a high-level selection of parameters, allowing various options depending on those selected. Of course I didn’t disable controls as appropriate, but basically you could select one of the 5 main options, then options for that, and any unavailable options would be disabled. The frequency would of course have to be converted from Hz to the nearest available option, and I think those hover tips would be useful for telling specifics, like Envelope Volume is a channel master volume or initial envelope value.
Then when you’re done, select “output settings” to set the settings and go to the next line. The forward and back buttons at the bottom allow you to scroll through the file, though I guess there should be an insert/delete line option.
There’s a few things that I forgot, like a preview wav button, and selecting where the files go (and optional code output), but hopefully you get the idea.
DogP
Attachments:
Could you guys elaborate on the Winamp plugin thing? I personally rarely use Winamp, but I don’t see how this generator as a plugin would be useful.
How do you plan on configuring the registers? Are you just wanting Winamp to play whatever is generated from a manually configured file rather than having to double click the wav file? Or maybe the plugin would look like a strange graphic equalizer and you could configure there? I have no experience w/ Winamp plugins, so I really doubt I’ll do it, but if anyone would like to, I’d be glad to help make it happen.
DogP
I was thinking more along the lines of having something like VGM files (http://www.smspower.org/music/uploads/Help/vgmspec150.txt) with values to write to the VSU and delays, and the input plugin would allow listening to these files directly in winamp.
DogP wrote:
How do you plan on configuring the registers? Are you just wanting Winamp to play whatever is generated from a manually configured file rather than having to double click the wav file? Or maybe the plugin would look like a strange graphic equalizer and you could configure there?
Either way would work, but I was just thinking of it like an IDE kind of thing: you edit the file (in my case, in UltraEdit) and then you open the txt file in Winamp and it does what your CLI utility does, except it sends the audio straight to the soundcard. Then it can be tweaked in the editor and, to test again, just hit “Play” (assuming you have a play button on your KB, which I do).
But, there are plenty of WA plugins with their own windows. They can even be skinnable. I really like your idea for an interface. The only things I would change are: 1) Probably use tabs instead of radio buttons 2) the “frames” should be something clickable, like the scenes in a video editing app or maybe a scrolling list at the side of the dialog, and 3) maybe a text pane that shows the resulting text file as you change it with the controls.
I just thought of another kind of plugin. You can make what’s called a “URL plugin”. They work by interpreting a URL of a certain type. For example: noise:// for white noise or line:// for Line-in. (I used to have a cool signal generator plugin, but I can’t find it :-() EDIT: I found it, plus the source-code! Yay! π
So, you could have something like: vsu://
I have no experience w/ Winamp plugins, so I really doubt I’ll do it, but if anyone would like to, I’d be glad to help make it happen.
I haven’t really written any, but I have studied and altered the code of a few of them. The main way you could help is by releasing the source, already! π
If I do it, I’ll probably start with the former kind (just an input plugin for the txt files) and then probably start on a fancy interface. I’ll also probably be making 2.x plugins, since they’re still supported by Winamp5 and are also backward compatible for older machines that can’t handle 5’s overhead.
- This reply was modified 14 years, 11 months ago by RunnerPack.
@mic:
That’s basically what he’s already made. It’s just a text format rather than binary. It’s less for getting sounds from existing games and more for developing sounds to put into new games.
However, if there’s an open-source WinAmp plugin for VGMs, that would be a good starting point for a VBSG plugin.
mic_ wrote:
I was thinking more along the lines of having something like VGM files (http://www.smspower.org/music/uploads/Help/vgmspec150.txt) with values to write to the VSU and delays, and the input plugin would allow listening to these files directly in winamp.
Ah… yeah, something could be done like that, though there’s currently no good way to get the values out. In Red Dragon (and probably Reality Boy) you can log accesses to a memory location, but it slows the emulator down to a crawl when there’s a lot of sound activity going on (because it’s logging to the hard drive). And because of that, and that Reality Boy isn’t cycle accurate, you really can’t get an accurate delay value (you could count cycles, but that’ll be wrong, and you could use a real PC timer, but that’d be wrong because the emu would be running really slow).
The real purpose of this was to help development, but yeah, I’ll post the source this weekend and you guys are free to do whatever you want with it. Let me know if you find any problems so I can fix them before posting. I’ve got a short list of things to compare on hardware that I’d like to make sure are correct, which I’ll probably do tonight (but that requires changing my VB side sound tester, which I hope will be easy to make the needed mods).
DogP
However, if there’s an open-source WinAmp plugin for VGMs, that would be a good starting point for a VBSG plugin.
And because of that, and that Reality Boy isn’t cycle accurate, you really can’t get an accurate delay value (you could count cycles, but that’ll be wrong, and you could use a real PC timer, but that’d be wrong because the emu would be running really slow
Logging only the sound registers can’t possibly be that slow, unless the emu author totally messed up the code. The point of VGM is that you log at a fixed sample rate (44100 Hz). So the emu only needs to check 44100 times per second if any of the sound register values have changed, and output the new value along with the delay (in samples) since the previous write.
The alternative to a logged format would be an executable format, like NSF/GBS etc, where you’d dump the V810 code and data necessary to play back the music, and let the winamp plugin emulate almost the entire VB. This is a better approach in some ways, but it takes a lot more work to implement.
mic_ wrote:
Logging only the sound registers can’t possibly be that slow, unless the emu author totally messed up the code. The point of VGM is that you log at a fixed sample rate (44100 Hz). So the emu only needs to check 44100 times per second if any of the sound register values have changed, and output the new value along with the delay (in samples) since the previous write.
Logging a small amount of changes isn’t too bad (like background music), but logging where there’s lots of changes, like speech takes forever. It doesn’t really have anything to do with the emu author… it’s just using fprintf to log an 8MB file a few bytes at a time is REALLY slow. I guess it could be optimized to log to memory, and then stream it out at once, but this isn’t what it was made for anyway.
Logging register values only 44100 times per second won’t work (or won’t be completely accurate), because the outputs depend on previous states, as well as the fact that Reality Boy doesn’t run at the correct speed (though it’s kinda close). I’ve gotta believe that dumping the entire sound register set 44100 times per second would bog things down as well. There’s also no current mechanism for interrupting 44100 times per second.
DogP
Logging a small amount of changes isn’t too bad (like background music), but logging where there’s lots of changes, like speech takes forever. It doesn’t really have anything to do with the emu author… it’s just using fprintf to log an 8MB file a few bytes at a time is REALLY slow.
No need for printf. VGM is a binary format, not a text format. And yeah, allocating even something like 128 or 256 MB for a buffer won’t be a problem for a computer bought in the last 7-8 years.
Logging register values only 44100 times per second won’t work (or won’t be completely accurate), because the outputs depend on previous states, as well as the fact that Reality Boy doesn’t run at the correct speed (though it’s kinda close). I’ve gotta believe that dumping the entire sound register set 44100 times per second would bog things down as well.
Well, you’ve got the previous state since every write is logged – it’s just done at a fixed rate. Surely it’ll be very rare for a game to change the sound registers at more than 44100 times/second for music playback purposes.
There already exists emulators for other systems that can do VGM logging; e.g. Kega Fusion, Dega and Meka. I think there’s a version of MAME that supports it as well, and there might be others. And it doesn’t really matter if the emulator runs faster than real-time, if you keep track of the number of V810 cycles you’ve emulated you can determine how many audio samples you need to generate.
mic_ wrote:
No need for printf. VGM is a binary format, not a text format. And yeah, allocating even something like 128 or 256 MB for a buffer won’t be a problem for a computer bought in the last 7-8 years.
Binary or not, you still need to get the data to disk somehow. And yeah, you could make a huge memory buffer, but that’d definitely have to be a different build… I wouldn’t want to waste 256MB in the normal emulator build when very few people would be using this feature.
mic_ wrote:
And it doesn’t really matter if the emulator runs faster than real-time, if you keep track of the number of V810 cycles you’ve emulated you can determine how many audio samples you need to generate.
DogP wrote:
Reality Boy isn’t cycle accurate, you really can’t get an accurate delay value (you could count cycles, but that’ll be wrong, and you could use a real PC timer, but that’d be wrong because the emu would be running really slow).
And while sampling 44100 times per second would probably get you sufficient sampling that you wouldn’t notice the difference between actual register write time and the time that it’s sampled, there’s certain things you’d likely miss, like if the SSTOP register is written w/ a 1, then 0, that should stop all channels, but wouldn’t catch it unless you sampled right at that instant. Also, like you said, all the registers shouldn’t be written 44.1k times per second, so you’re wasting ~235 bytes every time it’s sampled that it doesn’t change. Even with a 256MB buffer, that’s only ~25 seconds. You’d be better off just logging when something changes if it typically happens less often than 44100 times per second (although there’s some overhead from logging the time difference rather than a fixed delay, as well as the main problem of no stable timebase to log against).
DogP
Also, like you said, all the registers shouldn’t be written 44.1k times per second, so you’re wasting ~235 bytes every time it’s sampled that it doesn’t change. Even with a 256MB buffer, that’s only ~25 seconds.
No. A VGM logger only _checks_ if there have been any changes 44100 times/second. It outputs only those values that have changed, when they have changed.
So if you had a write to some sound register, then nothing happened for 16 ms, and then another write to a sound register, the output sequence would look something like:
0x55 aa nn (output nn to register aa)
0x62 (wait 1/60 s)
0x55 aa nn (output nn to register aa)
Ah, well that could work, except for the other issues I’ve pointed out. I guess to me it’d make the most sense to just log them as they happen. If you want a 44100Hz timebase, just have a counter running in the background at 44100Hz and log the “time” w/ the change, though as I said, none of the timing in RB is particularly accurate.
Personally, I don’t think emulation is up to speed for this task yet, but if anyone would like to work towards it, that’d definitely be nice to see.
DogP
Being able to log VB music from an emulator (from commercial games) wasn’t really what I was interested in anyway, though I guess some people would appreciate that.
What I wanted was just to have a format specified for VB music (be it rips or newly created songs), and a plugin for winamp that could play those files. I suggested piggy-backing on VGM since that would be one of the simpler solutions, but if a sub-format of PSF was chosen, that’d be ok with me as well.
Virtual Boy remains one of the few consoles out there (that more than 2 people have heard of) that doesn’t have a dedicated format for sound rips.
Well, if anyone wants to take charge of it, I’d be glad to help however I can, but since I have almost no experience with VG sound formats for the PC (nor really much interest), I don’t think I should take charge of it. I can give you whatever info you’d need on the VB audio technical side though.
DogP