In XMPlay sometimes the seek bar returns to the left (beginning) after seeking, though the music is played from the correct, sought position. Seems to happen when seeking to about halfway or more.
I still think an option for native SPC sample rate would be nice, for purity's sake.
mudlord, could you post your winamp interface code? Mouser's been bugging me about it and I'm wondering if I might spot whatever is causing his buffering issues.
I didn't mean to be an annoyance.... But I have been trying to see if I can find anything useful regarding the issue. I've been looking at old versions of 64th Note (because I thought it used to have this same problem. It doesn't, but it turns out it has a different "issue."). I've discovered a few interesting things. 64th Note v1.00 beta 8 and down don't handle prebuffering at all (as near as I can tell). In other words it ignores the settings I have for the output plugins. However, in 1.00b9 it appears to adhere to the buffering options (the "time display" stops at 20 sec. (I intentionally maxed the settings here to exagerate the problem), but continues playing until the buffer is empty. It also takes more CPU, implying it's rendering the next file). The source is available for 100b9, but not for 100b2-b8.
I realize that this is probably not useful, especially if HCS is willing to give your code a look over. I just wanted to be as helpful as I could. Hopefully this can be resolved better.
Also, you weren't rude in requesting me to post in this thread (as HCS already noted). And I do use an archive plugin for Winamp (rather extensively I might add). The problem is that all the VGMs I have came from Project2612, which are distributed in the VGZ form (grouped together in 1 big archive per game). If I understand you correctly, I'd have to extract every set, and every file in those sets, then repack them (after renaming them appropriately) into a new archive. While doable, I grabbed the Project2612 torrent. That's a lot of files to go through....
As for the buffer, if I were on my PC, then I'd have it around 5000-7000 (with a 3000 buffer when going to the next track). But this PC is garbage. 20000 isn't enough (but it does help), and files (2SFs and USFs mainly. I think I tried DSFs once, and they essentially locked Winamp up because they required too much CPU) usually don't play all the way through before they have to refill the buffer. In case you're wondering (I don't remember if I mentioned it already), this is a 450 mhz PC running WinXP.
Thanks again for looking into the issue, and for the plugin. Mouser X over and out.
In the past, I got VGZ support working. I'm not sure when that was. I suppose open sourcing this would help me tracking down and fixing these bugs I suppose :/
For me, the biggest limitations that in_mgme has is the song ending too early (hopefully what HCS said will be helpful there), lack of silence detection (that would help a lot on GBS files...), VGZ not working (is that just me?), and skipping through subsongs (which has already been addressed. It is a limitation, but it's one I can live with). Being able to read the M3U tags would be icing on the cake.
If all these issues are handled, then in_mgme would replace NotSoFatSo, NEZplug, in_vgm, and maybe even SNESAmp (I'm very satisfied with RSN extensions. However, since I use in_zip anyway, it wouldn't be a big deal to rename all the RSNs to RAR, thereby feeding them from in_zip through to in_mgme).
On the note of subsong skipping and in_zip.... When in_zip reads an archive, it adds entries to the playlist. Ex: Drag+drop an archive onto Winamp, Winamp loads the archive (be it ZIP, RAR, 7zip, etc.), in_zip reads the archive, and creates playlist entries that it understands (and thus when Winamp loads those playlist entries, they're forwarded directly to in_zip, which then extracts the file referenced, and forwards it to the correct plugin). Perhaps in_mgme could do something similar (it'd be optional). When a file with subsongs is loaded, add playlist entries for each subsong. These entries would specify exactly which subsong to play.
Here's what I'm seeing: Once M3U tags are implemented (you said there's already a means to read them in place, right?), in_mgme could (if the option is turned on to do so) add individual playlist entries for each subsong, using the M3U tags as the added entries. This way, the user loads one file (the NSF, GBS, etc.), and when Winamp gets to it, that file is then split up into multiple playlist entries (and the original file is removed from the playlist). I assume that since in_zip is able to add custom playlist entries to the playlist (immediatly after the archive in the playlist), that in_mgme could do the same, using the M3U tag specifications.
So far, that's the best I've got. Excluding your current method to handle subsongs (which, knowing your arguments now, makes good sense), I really can't think of anything else.
Did all that make sense? I'd be happy to provide more in-depth examples/explanations if they're needed, but I'm not sure if anything needs more clarification right now. Mouser X over and out.
The GBS support is not nearly as accurate as NEZplug++. One test case: Pokemon R/B/Y, a few subsongs in, Noise, or at least percussion desyncs and takes on a mind of its own.
Pretty sure NSF accuracy is inferior as well, especially the VRC6 emulation, etc. NEZplug++ is rock solid for 8-bit formats, as far as I can tell.
I haven't been able to play any VGZ. Looking into an archive plugin. The 7-Zip XMPlay plugin doesn't seem to work.
To the best of my recollection, these are the sets I either played with in_mgme, or was going to play with in_mgme. Some of them (the SPC sets for certain) I played from within their archive, using in_zip. Hopefully that's what you were looking for? Mouser X over.
Just so I'm clear on that, I assume you're refering to the buffering/song ending too soon problem? That's a problem I have with all files that have (and adhere to) track lengths. Specifically, I noticed it the most with the SPCs. So far, I haven't encountered serious problems with GBS/NSF files, other than that they play infinitely (even when 3 minutes is reached, they keep playing). Though, I would assume that, were they to stop when they were supposed to, that they too would suffer from the truncation issue.
Yes, I was referring to the silence detection issue. Which really, should have not been a problem since I do use the functions in the API to detect silence (unless its related to the problem HCS elaborated on).
I am well aware of the issue with SPCs, everyone seems to get that. Hopefully, hcs's code works fine.
anyway, here is a permalink to the files since I have no webspace:
Oh crap!!! I just remembered that the file I was using (regarding silence detection) was on my PC, and therefore it was being played with NEZplug++. The file isn't online (that I can find) anymore. It's a GBS rip by ugetab of all the sound effects from Link's Awakening. I requested it, because I wanted the "unlearned ocarina" song that's played when Link hasn't learned any songs yet. So there's a good chance my mentioning of silence detection was ill-founded. :( Sorry about that.
As for in_mgme, I assume the version from that link (the EXE) is the most recent one? I'm still having the same problem. I looked through in_mgme.txt, and I saw that you tested it for around 8000, so I tried that. Yes, it works with your buffer at that setting. With it at 10000 though, it doesn't (it cuts off 2-3 seconds too soon). This implies to me that you're doing some form of counting in the output. In my experience, a plugin that suffers from this problem cuts off at the point that the buffer is set to load the next file. This is not the case with in_mgme, as the cutoff is delayed to (I assume) exactly the amount you tested it at. This leads me to assume that, somewhere in your code, it's doing a count that only lasts up to 8000.
I also noticed your comment about in_gsf having the same problem. I downloaded in_gsf just now to try it out (since I didn't recall having this problem) along with Yoshi's Universal Gravitation (it takes the least amount of CPU, I hope). I listened to a few files, and they didn't end early (even though my buffer settings were all set to max). However, I'm fairly certain they ignored the buffer settings (the CPU didn't behave as I would expect it too, if the next file was being loaded/rendered). Of course I don't expect you to care about that. I just wanted to see for myself if the issue was duplicated there.
Also something of interest. When possible, I play songs through in_zip. Just to be certain in_zip wasn't getting in the way, I extracted the GSFs and SPCs, and tried them from a directory instead.
What is the default length for silence detection? With 64th Note, HCS had to put in a fix so that it would continue playing the file, even though it had rendered to the silence detection limit. To quote the 64th Note history text file:
09/09/05 - 64th Note v1.0 beta 4 released * silence detection now won't end a track until it's actually played to the point where the silence starts, which should fix things for users with large buffers (before the track would end as soon as the specified amount of silence was *rendered*)
What I'm wondering is, if your silence detection is high enough (I realize 8-9 seconds is very high for silence detection. I have encountered some games that need more than that though), if it would suffer from the same problem. That is, the song cuts off when the silence is rendered, rather than when the silence is actually reached by the user/speakers.
I'm wracking my brains trying to come up with ways I can help out more to narrow down the problem. Right now though, I can't do any more than I already have. :( Mouser X over.
Silence detection is done via a GME API function. Maybe it is indeed related to the sample buffer issue, and I know that is at least a pressing issue for whats there currently.
And I only tested up to 8000ms. And yes, beyond that, there is detection issues. Which leads to the sample buffer issue, since detecting silence involves counting of null samples.
So: I really should try how hcs does it. Or maybe dr0 can lend a hand? I honestly am not that cluey with audio coding (my experience is in graphics programming, however)
And in_zip shouldnt affect it at all. It seems definately the sample buffer issue rearing its ugly head.
And in_zip shouldnt affect it at all. i'd hope in_zip wasn't the cause of any off the observed issues though the publically available version of the plugin badly needs to be updated (i know some people have had newer test builds but nother ever final has been released).
now i've only had a quick skim through this thread but if vgz is a gzip based format, would it be of any benefit if i implement reading of gzip based archives in in_zip? would also be a good incentive for me to start working on it a bit more and getting a newer 0.7x based version out the door...
I figured as much, but in_zip has caused strange issues in the past, so I just wanted to get rid of anything that might, somehow, interfere. Also, since the 450 mhz PC isn't mine (what I've been using to get online), it doesn't have the in_zip beta.
As for gzip support with in_zip, I don't know if that would help. Looking at the VGZs with 7zip, the files don't appear to have an extension. As such, even if in_zip supported gzip, it wouldn't know where to forward the files to, unless in_zip had a special built-in rule that says "if reading from a VGZ, send the extracted file to VGM player." Though, because there's no extension, you'd probably have to add one when you extract it. Not to mention that you run into the problem of an archive within an archive (I didn't think in_zip handled those very well, but I don't remember).
I'm willing to help out in any way I can, of course. So if you want to add gzip support to in_zip, and attempt to get VGZs working using that method, I'd be more than willing to play the part of the guinea pig. After all, isn't it usually my PC that runs into the most problems? :P
Sadly, it is very likely that I won't be available until Sunday or Monday for most of this stuff. I still have homework to do, tests to take, and sleep to get. By the end of next week, I'll hopefully be done with all this stuff. And OH WILL THAT BE A HAPPY DAY!!! Mouser X over and out.
fyi mouser, gzip is stream-oriented; it doesn't have any identifying metadata like file name, so he'd have to do something like that. Typically one names gzipped files like blah.ext.gz to get around this (when extracting the .gz extension is stripped off), but there is also the convention of calling gzipped .tars .tgz instead of .tar.gz. It seems reasonable in this instance to name the .vgz output ".vgm" when passing it on to the real plugin.
For RSN, xmp-rar.dll works perfectly. Drag-and-drop an RSN into the playlist and all the SPCs are loaded (Mouser X, without having to rename RSN to RAR!)
This may work simply because the RSNs contain SPCs with extensions.
Applying this to VGZ, I can't say if a gzip plugin would work because there is no gzip plugin to test, and the contained VGMs lack the *.VGM extension.
...What hcs said. Then again, why don't input plugins/media players do deeper checking than simple file extensions? I vaguely remember something about XMPlay or a certain plugin doing so...
SmartOne: If I setup in_zip correctly, it would handle the RSNs directly as well. Renaming 1 or 2 RSNs for testing is easier than changing the necessary settings (changing an entire directory via command line/batch files would be about equal difficulty to changing the settings though). If I were to replace SNESAmp entirely (which is very possible for this plugin), I'd go and change the necessary settings.
I'm well aware that there are people who like XMplay. I like Winamp. Call me stubborn, but I don't plan on switching anytime soon (I certainly would have already if it was of even remote interest to me). Mouser X over and out.
Yay!!! Great news!!! The buffer issue is fixed. At least, as near as I can tell. I've maxed out the buffer settings, and the song plays all the way through. Something interesting (leave this in!) is that unlike most of the plugins I've seen where, as soon as the "buffer ahead on track change" is reached, the time display shows the next track's time and sits there, doing nothing, until the current track is done. Once the current track is over, the time display starts to change (as it should, since the track is now playing). With in_mgme, the next track's time doesn't display until 7-8 sec. after the "buffer ahead on track change" is reached. Once displayed, it acts as usual (doing nothing until current song is over). But this is a nice feature! Like I said, I don't see that very often. And with my usual setting of 3000, I'll never have to worry about the time displayed showing the next track's time.
Nicely done!!! Thanks a bunch! Maybe I should hunt down some other plugins that suffer from the truncation problem, and point them to this thread. It might help.
Something I just noticed (since I've never seen the end of the track before...) is that when listening to "Mahoujin GuruGuru (1995)(TamTam)(Enix) \ mgg-02.spc", "Mahoujin GuruGuru (1995)(TamTam)(Enix) \ mgg-continue.spc", and "Mahoujin GuruGuru (1995)(TamTam)(Enix) \ mgg-43.spc" (they were among the shortest SPCs that were over 25 sec. long) they play to the end (the entire 30 sec.), but then they go a little further (about 4-5 seconds). It seems to me that the time, as displayed by Winamp, doesn't take into account the fade time. Is this the case? If you're aware of that, any ideas on how easy it will be to fix (or if it will be fixed at all)? Just thought I should point that out in case you didn't notice it. Mouser X over and out.
Well, if the sample buffer issues are fixed, it could be related to how fading is done o:. Not sure on the best approaches to fix that (kode54, any thoughts?). Maybe setting the fade time after the initial calc is done (since GME allows fade length to be changed during playback). I guess I need to now round up more SPC sets xD
Mudlord, VGZs don't work because there's no gzip archive plugin, plus the VGMs lack extensions(?). (Unless I try this in_zip Mouser X is talking about? I'd rather have another offical XMPlay archive plugin.)
Winamp = filename (extension) to determine appropriate plugin
On Blargg's site, it says that GME supports VGZ. I assumed the code to handle VGZ was already in place with the GME library stuff. Since mudlord doesn't plan on supporting VGZ files directly, I'm left to assume that I was mistaken, and that GME doesn't contain the code necessary to handle VGZ natively. Is that the case?
As for in_zip, it doesn't support gzip yet, but DrO mentioned that he was considering putting gzip support in. So, it seems to me that currently, the only way to play VGZ files (using in_mgme)is to extract their contents, and then load the results into your player of choice (adding file extensions if necessary). While doable, I would say that it'd be better to stick with in_vgm, since it supports VGZ.
Since we're on the topic of VGMs anyway, I'd like to mention some interesting behavior. When playing VGM files, the fade time appears to be included in Winamp's displayed time (whereas I don't think fade time is included when displaying SPC times). However, unlike SPCs, when "buffer ahead on track change" is hit, the next song's time is displayed. If you have it set to 20000 (I tried it for testing purposes. I normally have it set at 3000, which is almost nothing), then for 20 sec., the next song's time is displayed, doing nothing. This is NOT a big deal. It still plays the entire song (which is far more important). I just thought it was odd that SPCs and VGMs are being handled differently. Mouser X over and out.
@Mouser X: VGZ support relies on Zlib. For some reason when I compile it in, it refuses to co-operate (the crashes)
I did VGM stuff differently due to some test files I had that have loop times set and stuff. Looking at the code would show you precisely how its calculated. Not sure on the stuff with buffer ahead though.
I guess I could DL more stuff and see if I can get a uniform timing algo or something, depending on what fields are set (like for looping times and stuff). I guess this is also the time for coming up for a decent timing algo (another thing I really wanted to improve)
@SmartOne: You were right about XMPlay. Archives are opened depending on the file header. So you can load VGZs (which are renamed ZIPs) and RSNs (renamed RARs)regardless of its true extension. Not sure on the exact mechanics of in_zip though.
in_zip works on an extension and file header based check with it handling anything in a zip:// style entry or whatever extension has been associated with the plugin (as the other winamp plugins generally offer). then in_zip will work out the archive type from the file header, extract out the file(s) (depending on the extraction rules) and then forwards things on to the relevant input plugin (mainly based on file extension but also partly on a known plugin list for certain aspects to ensure correct transparency between the archive and the required input plugin).
handling off these vgz files would just require an extraction rule off sorts (implemented by default like i do with the re-writing off the _lib= tag in extracted xSF sets) that would extract and forward on these unnamed files to either in_vgm(or whatever it's named now - haven't really been following it's development much of late) or to in_mgme. now i'd assume people would only be using one off these two plugins at the time or am i wrong in this thinking? if so which one would be looking to have a higher priority for usage with the extraction rule?
zlib isn't too hard to use, if it's crashing you should check your code against some example stuff, or you might need to build the library a different way yourself. I had to do this with some stuff (in particular HW) but eh...
Wow, even blargg's VGM core with his resampling gives the hi-hat sounds in the Streets of Rage games a pitch. I thought high quality resampling would fix that?
GME currently uses code from Gens for VGM playback. kode54's build uses a modified version of MAME stuff (IIRC with the recent stuff from Nemesis), and AamirM's build of my stuff uses his own custom core, with blargg's FIR resampler in use.
Mudlord, be sure to render Mega Drive VGMs in native YM2612 frequency (53267 Hz).
This is required for correct playback of some instruments (08 Episode 1, Page 2-2.vgm from Comix Zone set is a good test case, as it has an instrument that glitches otherwise played at song beginning).
I use /O1 with Link-Time Code Generation. There was a bug with MSVC2008 importing the project files, so it was originally not using any optimization at all.
Also, I sent this bug to blargg, but feel free to lend a hand, or mail it to him, if you know a way of contacting him other than his Gmail account.
First, the macro CPU_READ_FAST_ in gb_cpu_io.h checks against the APU register range with <= Gb_Apu::register_count, while it should be <.
Second, there's some invalid opcode or other execution madness going on that not only crashes the GBS, it crashes the emulator as well. Somehow, the 16-bit program counter is getting set to 0x12000 or something, crashing the bank selection code by pulling a bank offset out of range of the table size.
Based on what I hear from my crappy laptop speakers, there are no more "whoppies" in the Phantasy Star II "Restoration" track, which implies you've changed to the Genesis Plus GX core and thus fixed the SSG-EG. Great! Still has resampling issues for the Streets of Rage hi-hats.
The format selection isn't working in XMPlay, or possibly at all.
Now that you have them at 32 kHz, I'm thinking it a good idea to have an option that upsamples GME-somely to 44.1 kHz.
Playing audio digitally over SPDIF on my home theater system, 44.1 kHz is nice to have to avoid possible low-quality sound driver/hardware resampling. For regular listening with my USB DAC, 32 kHz is optimal. :D
Hey Mudlord, this could be a bug caused by Windows 7 RC or it is an actual genuine bug.
the track seek function works sporadically, seeking forward multiple and rarely if ever allowing to skip back some tracks in a NSF file.
MGME 0.5 Final. Winamp v5.552 and MGME v1.0 alpha.
It seems to skip sporadically backwards/forwards until it passes the defined default track in the NSF upon which it works fine except you can't go back before the default starting track...
Like I have a Power Blade NSF file that defaults to track 68 right? MGME plays at track "random" and the track seek functions don't work correctly untill you either start listening to track 68 or a later track. You can't skip back before track 68 though.
eh, it is just screwed for no real reason. Ninja Gaiden 2 mostly plays well up to like track 27 or near there then the NEXT / PREVIOUS buttons function sporadically.
And this is why I am adding the format select: Because Winamp is utter shit and doesn't support subsongs natively, workarounds have to be used, and these are prone to be buggy.
mudlord: There's not much left to tell, most winamp plugins that don't have the next subsong hacked in (like, say, NotSoFatso) work this way. NEZPlug, NSFPlug, in_wsr, in_tfmx, in_asap, etc.
1) when playing a song in a NSF file such as track 9 or so, it will randomly start skipping from song to song every few seconds. this bug is fixed by setting MGME to play songs forever.
So you used blargg's modified MAME core, not eke-eke's from GenesisPlusGX? What's the difference?
GAH I can't build the static library libz.a because of some stupid VS_VERSION_INFO thing. This is so frustrating.
Grabbed a precompiled version of libz.a, cleared whatever the hell the Linker had listed for external libraries, and added the file. Finally got it to poop out the DLL. Incredible.
The difference being: out of laziness. Can't be bothered redoing the whole VGM emu for the sake of thing when whats in there sounds fine :/.
Glad you got it to compile. It sure can do with some cleaning, plus some things can be finished off, like the file format selection yanked from NEZPlug.....
It shouldn't lack it, as all my public files are there.
As for the call hierarchy, it all stems from calling functions in GME from gme.h and from utils.h. Nothing remotely complex. Though, all the stuff in gme.h, is a wrapper to the internal stuff in GME which is best left to blargg to describe.
You could also look at the official GME redist and its examples to see how Game_Music_Emu actually works.
Specifically, I was confused about where the heck PluginOptions came from. I just figured out that it's the (secondary?) name of the struct options because it's after the brackets. Structs are cool... I guess... Coming from only Java experience, I get to figure out all this funny C (C++?) syntax. :P
Attempting to add GSF support via VBA-M, the GNU GCC Compiler doesn't seem to like Gb_Apu_State.cpp very much... 23 errors and 2 warnings, all from that file.
This is impossible. Everything is connected to everthing else. I've sat here for hours commenting out junk. About to give up.
I can't compile the Highly Advanced plugin you provided that uses blargg's stuff for resampling. It's the stupid afxres.h in the resource file. Apparently Visual C++ doesn't support MFC, or something? What a mess. Maybe I'll try hand editing your MGME GUI into Highly Advanced...
I don't know anything about anything, so don't feel bad.
Hey, I got Highly Advanced (without libresample) to compile!!! I even went ahead and converted the resources to Ms Shell Dlg 2 format, I think...
Anyway, fully working GUI and no more stinky resource file including afxres.h and causing unhappiness. Yay!
About implementing blarrg's sound library and updating to his GB APU and latest VBA-M... I think I'll need some help. Assuming I can get that working, the plan is to stick it into MGME and burn Highly Advanced at the stake. Friggin' sweet, right?
There is currently talk of redoing VBA entirely from scratch. Basically, we are thinking of something Gambatte like in terms of modularity, while being accurate enough but not accurate to the point where its absolutely stupid and insane (eg. bsnes and that other shit)
MGME and HA? Well, I released the source as BSD, so heck, if you wanna do that, go ahead! The updating to use blargg's stuff though will take time....
Would you mind explaining (I noticed similar code in MGME:)
while (mod.outMod->CanWrite() < ((ret*sndNumChannels*(sndBitsPerSample/8))<<(mod.dsp_isactive()?1:0))) Sleep(50);
Natural language so far: While the input module's out module's CanWrite() function returns an integer that is less than (sound buffer length) * (number of channels) * (sound bytes per sample) left bitshift (input module's dsp_isactive() function if true return 1 if false return 0), Waste time for 50 milliseconds;
While the output plugin can't accept how many samples we want to play, wait.
ret = samples sndNumChannels = channel count, so ret*sndNumChannels = samples counting both channels *sndBitsPersample/8 computes how many bytes (bits divided by 8) that many samples will take
The left shift is because the dsp is active you need potentially twice as much space in the output buffer (dsp plugins can do stuff like double each sample two slow down playback). Left shift by 0 (what you get when mod.dsp_isactive() is false) is multiplication by 1, left shift by 1 (when mod.dsp_isactive() is true) is multiplication by 2, for the doubling.