ADSR -- a good example of how this doesn't work properly, is the Menu theme of Mario Kart DS ... one of the piano instruments sounds like a constant tone.
Krude, the playback is done via either my Winamp plugin or kode54's foobar2000 plugin. Long story short, I basically took a DS library called FeOS Sound System, which was designed for a DS OS called FeOS, both being developed by fincs. I had to modify it because it was DS-based and I needed to play back on a PC, without emulating the DS's ARM7. The plugin reads from NCSFs, which are created from the SDAT of a DS ROM, the tools are in the first post.
I think I do mention that those runtimes are needed in the docs for the plugin. :P
Anyways, considering that the thread got bumped, I should probably mention that I've done nothing with the tools. ;_; Up until the end of last month, I was working on other video game music related projects, and then I got a job and now my free time is at a disadvantage. The good news is that the tools do still work, the bad news being just that they are still not all that user friendly yet. I'll try to find some time to work on them again eventually, but unless someone else wants to help with adding things to them, they probably won't get updates any time soon.
So yeah... I've been pretty silent on this thread, despite that I've done updates to the plugin. (The tools, not so much, other than a fix I'll mention.) Gotta break the silence. :D
So, I'm going to list what I've done with the plugin in the last 4 months (since that was the earliest I made any changes to it):
* Changed the Sinc interpolation from the Hann window to the Lanczos window. (As an aside, I am still not sure if this is the best window or not.)
* Removed the Cosine, 4-Point B-Spline, 6-Point B-Spline, and 6-Point Osculating interpolations. The reasoning behind this is because Cosine is just horrible in general and the other 3 "muddied" the sound, because they actually caused lower volumes in a lot of cases.
* Added 4-Point and 6-Point Legrange interpolations in place of the removed ones.
* Volume issues have been completely fixed. A few things here: the volume level that FSS was calculating needed to be clamped as it was actually going over the array bounds of the volume table; the default volume of a track is 127, not 64; the SSEQ volume from the INFO section is being correctly handled now, it was being handled incorrectly before; master volume was already being applied by FSS so I didn't need to apply it again.
* Implemented the commands that were not implemented in FSS; this is basically the random, variable, and comparison commands. This fixes almost all playback issues with tracks that utilized these commands. This implementation was also applied to the SSEQ timer of the SDAT tools so now just about every single SSEQ can be timed correctly.
* Allocation of SSEQ tracks was moved from the player to the SSEQ command handler, after I found some KSSU tracks that didn't have their "opentrack" commands (0x93) immediately after the "alloctrack" command (0xFE). This change fixes those KSSU tracks. Granted, the tracks I found like this were sound effects, but still, it was a good thing to fix.
Now, most of the above is included in the Winamp plugin that is on my NCSF site. The plugin isn't FULLY up to date yet, because I am still looking into some things.
Specifically, and mostly because of the Etrian Odyssey 3 track that Knurek brought up earlier in the thread, I realized what the problem is NOW (why I didn't last year, I'm not sure...), and it has to do with the channel allocation of FSS. The Labyrinth VI track from EO3 utilizes some PSG Wave sounds in addition to standard PCM sounds. The PSG Waves are killing off the PCMs. I've yet to figure out a fix for it, and I've brought it up with fincs to see if he can help with that.
All in all, I do believe that the plugin will be in pretty good shape once that issue is fixed. I do think that I may need to check on using a different windowing function for the Sinc interpolation, though. The track labeled SERPANT in Mega Man ZX sounds a bit bad with Sinc (and both Lagrange) interpolation but sounds somewhat fine with Linear interpolation. Granted, my comparison is DeSmuME/2SF with Linear interpolation, so it might not be the best comparison. But it is definitely an example of something sounding bad with "better" interpolation.
Great to hear, I've been using NCSF for portable music history with NDS games that don't work with CaitSith2's driver, I'll make sure to have the latest plugin linked there.
I'm still looking into the EO3 sound issue. My gut feeling says that it is because FSS isn't checking if a channel has just been allocated (i.e. being in the "start" state), so I tried to change that, and while it sounds better, it still sounds a tad different than the 2SF version. I'm going to get the EO3 OST and check how it sounds there, to see which sounds closer to the correct one. I've yet to hear from fincs, but I did post the question on IRC in the middle of the night (for me) so he might not have been around at the time.
OK, so I've narrowed down where the problem is. It isn't in channel allocation, it is in the ADSR calculations. What I have yet to figure out is how to fix it, I'm still gathering data to determine a fix. But it would explain why sequences like that EO3 track are getting messed up, because the channel is playing the sound for too long and thus sounds get killed off in the process. It would also explain why it looked like the NCSFs were getting ahead of their 2SF counterparts. I'll make an update once I've figured out a fix for this.
Maybe you can implement those resamplers into my resampler.[ch] singleton thing? At least if you do that there, it would help to make coefficient tables for those, so the resampler loop can be vectorized.
It currently has zero order hold (no interpolation), BLEP (band limited steps, basically the same as ZOH but band limited), linear, cubic, and 3 term Nuttal windowed sinc, which I found to be about the best window for reducing the aliasing of resampling an extreme case of sine sweep. Throw in the others, and you can just use the whole thing like a library.
It's an easy to use resampler, since all you need to do is pump it with input samples until its buffer is full, then pull out samples one at a time. It supports both fixed and floating point input/output, but operates on floating point internally.
It could use some optimization, I suppose. If you want, the latest version is located in my modplay repository, on Bitbucket.
Well, good news. After checking things with fincs, he finally figured out the issue. It turns out that it actually was the channel allocation at fault. PSG and Noise channels were being allocated in reverse.
I had also fixed the calculation of the attack rate, as what is listed on kiwids about the calculation is actually wrong. Just so it is know, basically, the table on kiwids for the amplitude values of the attack rates are correct, and the calculation is actually attack rate = attack rate * amplitude value / 256 (not 255 like they listed). On top of that, it appears as if the attack rate calculation will never allow the same volume table index to be used consecutively.
Other things I did were fix a few defaults and use the Nutall 3-term window that kode54 brought up. As far as the resampler idea does, I'll consider it in the future, but for the moment, I'll leave the NCSF plugin alone. Also, as for implementing the Legrange interpolations into that resampler, I'm not against it, but I have no idea how to translate Olli Niemitalo's algorithms into a lookup table.
So yeah, I believe that now, the plugin is as good as it'll ever be, barring any weird things that come up. The current version, v1.10.3, is in the ZIP on my website. I'll have to work with kode54 so foo_input_ncsf can also be updated. EDIT: I've sent kode54 some pull requests to update foo_input_ncsf.
Next step is to stop being lazy about the SDAT tools. <.< Ideally I will want to create the 2SF->NCSF tool and make it so the NDS->NCSF tool can output something similar to an SMAP for easier choosing of the SSEQs to include. I also want to look into stripping of the SBNKs and/or SWARs, since Knurek did mention that being a big point for optimization that I'm not doing.
Something else that was mentioned to me by Henke37, SDATs have these items called PLAYERs. They are not actual players, but rather, they control things like the maximum number of concurrent sequences, heap size, and most importantly for the NCSF plugin, a bitmask of channels that can be allocated. I've applied this to the plugin, and I have also updated the SDAT tools so the PLAYERs are not stripped from the SDAT like before. I have not updated the ZIPs yet, but will do so shortly. I will also be updating the website to mention this, as I consider this a specification change, and on top of that, I have made it so things are backwards compatible to NCSFs made without the PLAYERs in the SDAT.
From what I had seen, some of Square-Enix's games set the channel mask, as did Time Hollow.
In any case, I think today or tomorrow, I'll work on making the 2SF->NCSF tool. It shouldn't be too difficult, as I already have some code for it from the 2SF tag copier. It'll only support 2SFs made using Caitsith2's Legacy of Ys driver, but since that probably covers 99% of the existing 2SFs, it shouldn't be a problem.
I just committed the update to my GitHub that contains the 2SF->NCSF converter. I haven't tested every 2SF set out there (the 2SF archive from joshw.info contained 1555 7zip files and not even all of them has 2SFs in them), but I tested out some here and there.
There are some things to note about it. It will only work on 2SFs made using the Legacy of Ys driver. Thus, it cannot handle older-style 2SFs that used the Yoshi's Island driver, for instance, or any that use a driver other than the Legacy of Ys driver. It also combines everything into a single SDAT (and thus a single NCSFLIB), but it is not exactly the same as how NDStoNCSF does it. I've designed the tool so it does nothing more than a conversion and re-timing of the sequences. If you want more control over the process, I'd suggest using the original ROM with NDStoNCSF.
I'll be updating the ZIPs on my website shortly. The next task I plan on working on will be to make NDStoNCSF output and utilize something similar to an SMAP (it won't be identical, but fairly similar). This should help with some of the more crazy sets that require a lot more fine-tuning than what can be done with the command line includes and excludes. I'm looking at you, Sonic Rush Adventure. *stare* (As a side note, that game is why 2SFtoNCSF creates its SDAT the way it does, because the 2SF set is set up in a crazy way.)
As for when that will be done, I can't say for sure. I won't be starting work on that today, and I'm busy up until Sunday evening. I might start on it then or on Monday.
edited 7:29 PM EDT October 29, 2014
by TwinkTickler at 11:24 PM EDT on October 29, 2014
Well, updated my GitHub with the latest update to the SDAT tools. Like I mentioned in my last post, this allows the NDStoNCSF tool to output an SMAP-like file that can be used to include only the SSEQs that are left uncommented in the file. A good example of this is the nearly 75KB monstrosity of Sonic Rush Adventure's SDAT. (Seriously, what was Dimps thinking?)
Basically, to use this, use the -s or --create-smap option with the filename you want to store the SMAP in (it'll be relative to the output directory). Modify it like in my example above, and then run the tool again with the -S or --use-smap option. Please note that the short versions of the command-line options are case-sensitive!
Hopefully this'll make it MUCH easier to include/exclude SSEQs when creating an NCSF set. Now, at the moment, it doesn't allow you to use the -i and -x (include and exclude) options when using SMAPs, nor does it allow you to use the -a (auto) option. The former is because of how the SMAP handling is being done, but if it turns out that it would be better to allow them to work together, then I may change that in the future. The latter is because the automatic mode is part of the include/exclude process and not really needed when you've already done that work with the SMAP.
I know I said I was gonna have all of the above done earlier in the week, but I got a little under-the-weather from the weekend and it took me a bit to get this done as a result.
My next goal with the tools is to work on more advanced stripping of the SBNKs and SWARs. Ideally, I'd parse through the SSEQs, look for which instruments in each bank are being used as well as which SWAVs in the wave archives are being used, and get rid of the ones that aren't being used at all. That should save some space in the final SDAT's creation.
by nothingtosay at 12:51 AM EST on November 14, 2014
You wouldn't happen to have any idea why StarFox Command doesn't get all its music dumped, would you? It happens both with VGMToolbox doing NDSTo2SF and with your utility. Or maybe it does all get ripped, but some files are just nonfunctional. I get 130 tracks with your utility, but one, SSEQ004b, gives an error message and 26 of them display the default 3:00 length and hang foobar if I try to play them.
2SFs don't have that problem, but I suspect they may have a different one. VGMToolbox also produces 130 2SFs, but 25 are two seconds long, very loud, and seem like they would be sound effects but I don't think they are (though it's been a long time since I played the game), and there's still another one that gives an error message.
You don't have to play long into the game to hear music that doesn't get ripped, and it's definitely sequenced as muting instrument voices in DeSmuME will show. Just wondered if you might have some theory, and I'll provide any more information or help I can if you ask for it.
An update in the tools department. I haven't updated the ZIP yet, but I have committed an update to my Github that allows the tools to strip the excessive data out of the SBNKs. Right now, only the NDStoNCSF tool utilizes this. I also need to modify parts of it so I can prepare it to be able to strip the SWARs as well.
Replies to the previous posts:
nothingtosay:
From a quick lookover, using a tool I derived from the FSS track handler in the NCSF SSEQ player, those sequences from Star Fox Command that don't time or play properly are probably because of 0-length wait periods. Because of that, they cause the track parser to get stuck in an infinite loop. There really isn't much I can do about that.
Lunar:
As Knurek mentioned, but I'll elaborate, NCSF is basically designed around the idea of playing Nitro Composer SSEQs that are contained in standard-format SDAT files. If a game uses an alternate method for its music, such as ADX streamed files (like The World Ends with You) or Procyon sequenced music (like Luminous Arc), then NCSF won't work for them.
In the case of Zombie Daisuki, they appear to have used the Procyon sound tools, so it can't be dumped with either 2SF or NCSF.
I'm sure at some point in the future, someone will figure out how all the Procyon sound formats work, but as of right now, the only one that has been figured out is the sadl streamed format as it is in Professor Layton and the Curious Village (which isn't the only game to use that particular format). But even if the format for Procyon music is figured out, I'm not sure what I'll do with it as far as NCSF goes. When I named the format, I picked the name because it was meant to handle only Nitro Composer SSEQs, which is technically what 2SF is also doing.
That's not to say that Procyon sound tools games cannot be dumped as 2SF, just that they cannot be dumped automatically using our current dumping tools or techniques. Or am I assuming incorrectly that 2SF supports running arbitrary NDS ROM dumps that happen to produce sound?
You are correct, 2SF basically uses a Nintendo DS ROM as its PSF program section, so anything is possible as long as it can run through a DS emulator (like DeSmuME since that is the emulator used by the 2SF plugins out there currently, I believe). So yeah, all it would take is a proper ROM equipped to play Procyon sequences (and maybe streams) and they could be made into 2SFs. The only reason I said that 2SFs only use SSEQs like NCSF does is because the current dumping tools and techniques utilize a ROM meant to play SSEQs. But on top of that, since SSEQs are contained within an SDAT, that also poses a small problem to making an all-purpose ROM for Procyon sequences because they are separate files, not contained within one file.
Personally, I'd rather figure out the Procyon format(s) and do something similar to what I did with SSEQs. Whether that would be an addition to NCSF or a separate format, I can't say for sure.
Somebody emailed me about such a thing a week or two ago, also asking about Procyon ADPCM from some part of vgmstream. I tried my best to explain how the ADPCM decoder worked for that format, and never heard back from them.
Well, from what I've seen, as far as Procyon streams go, there appears to be 2 different formats for sadl. One of them is the one used in Professor Layton and the Curious Village (and I've also seen it in some other games, I can't recall which ones), and one used in Luminous Arc. The Luminous Arc sadl files are in an entirely different format than the Layton one. I'm not even sure why, nor did I ever look into how much difference there actually was.
So after some delays in actually getting around to adding in the SWAR/SWAV stipping, plus some bugs that were cropping up (partially because of me) and some other changes in the code, I have finally got that all squared away in the SDAT tools. In the process, I also discovered an unsigned integer underflow if an ADPCM SWAV's loop offset is 0, since the code tries to subtract 1 from that (oops).
I've updated the ZIPs for both in_ncsf and the SDAT tools. I'll get around to doing a pull request to kode54 to update foo_input_ncsf. in_ncsf is now at v1.11.1, and I'll just say that NDStoNCSF in the SDAT tools is at v1.7 (I'm not going to list all the tools).
Going back to the start of the thread to check on things...
Knurek had mentioned the sequence SEQ_glad from Sonic Colors having a volume of 0. Well, that particular sequence isn't even a valid sequence to begin with. It is only 40 bytes long and has 4 commands: turn off note wait, set the tempo to 160, set the patch to 11, set the volume to 127. The end of the track (and the file) happens after that.
Something else Knurek mentioned that will probably require a specification change (and probably manual processing) is edits to the NCSFLIB from the MININCSFs. I haven't really looked into the games he mentioned that would benefit from that, but I'll keep it in mind for a future revision.
I believe the next thing I am going to do for the NDStoNCSF tool is add something to allow it to search for streamed formats, like STRMs inside of SDATs or ADXs, that sort of thing.
As always, if anyone else has suggestions, comments, questions, please feel free to tell me.
I wasn't able to look into it until now because I was out of town, but after looking things over, it seems that something in the bank and wave archive stripping has broken that particular file. I'll have to do some research as to why that happened.
So, I did narrow down where the problem was. I was not handling the implicit patch 0 that is the default for a sequence. The result was that patch 0 would get stripped out if it wasn't explicitly used in any sequences. I'll be pushing the fix to my git shortly, but I won't have a new compiled version up until I work on some of the larger updates I've got. In the meantime, if anyone runs into the problem, they will have to compile the program themselves.
Well, that one is a silly problem I caused. Part of the code that determines if a bank's wave archives need stripping was setting a bank to 65535 (0xFFFF), but then it wasn't checking if it was set to that when adding the wave archives to the list of them. I've fixed the crash, but considering how many sequences are in WarioWare Touched, I haven't checked which files were causing it and if they still play correctly. In any case, I've updated the code on GitHub with the fix.
I have not thought about that. If you could point me at said shell extension for NDS files, I could probably look into it, assuming that the code for that is actually available. If not, I could add it to the list, but I'm not sure when I'd get around to it.
First thing I found when I searched for one was a 3DS one. I suppose the next question would be what kind of information you'd want to get, and from what files exactly. It'll be something that I'll put on the list but as I said before, I'm not sure when I'll get around to it.
Found a sequence that doesn't playback correctly. BGM_ZOMBIES from plants vs zombies. My own analysis says it's an exceptionally simple sequence. Only one track and no flow control, not even a jump at the end. But it does have two tricky things: notewait is on and notes have a length of 0.