The oscillators are partially implemented for playback, but not for SF2 export. I think the volume and pan oscillators are working (need to properly test) for playback. For pitch and LPF(?) the oscillator value calculation works for all wave shapes, but the interpolator can't handle extremely rapid pitch changes at the moment (I intend to debug this at some point because it's kind of a big problem, think it has to do with the counter resetting), so the code that loads the pitch oscillators into a playback sample is currently commented out. LPF oscillators aren't implemented beyond the general oscillator value calculation, and that's also because I did something wrong writing my LPF classes causing them to output silence.
Now I think I might be able to encode the oscillators in SF2 as modulators, but the only reason I haven't thus far is laziness. There's also a weird bug with pan scaling and the envelopes are a rough estimate for now. Other than that, seems to work alright. I'm able to open the resulting files in Polyphone and play them back nicely. Just needs a bit of tweaking to sound as accurate as possible. I definitely intend to fix/add these things, just haven't done so yet.
The explorer GUI tool is here. I don't really consider it polished enough to officially "release" quite yet (especially since my last few changes broke it), but I like using GitHub to bounce my code between computers cleanly so eh. It's all Java since Java is my crutch language and I keep going "eh, it'll just be a quick little applet, don't need to pull out the C...". I believe the JAR in /jar/ was built before I broke the type detection system, so if you wanted to check out a vastly inferior version of all the existing DS ROM explorers, that should do the trick . It does detect and play back SMD/SWD though (if not still a bit roughly), so that's something!
Noooow unfortunately, the SF2 export buttons on the GUI seem to be outputting air for some reason. The issue isn't obvious so might take me a few to figure out why it's not writing anything. Some link is probably broken in the callback chain.
However, the conversion and writing methods themselves absolutely work! At least, last I checked!
THESE are in my game formats library -- class is waffeoRai_soundbank.procyon.SWD
The little main test in the same package (SMDTest) has an example of how to do it since I export to SF2 as a means of debugging soundbanks, but here's basically all you would need to do to call it directly:
String swd_waves_path = "mydir/bgm.swd"; //The file containing the wave data
String swd_art_path = "mydir/bgm0025.swd"; //The file containing articulation data, here I just picked Apple Woods
String sf2_path = "mydir/bgm0025.sf2";
//Open a FileBuffer. This is my file wrapper class that handles multi-byte fields.
//The second arg is byte order as a bool (false is LE)
FileBuffer filedata = FileBuffer.createBuffer(swd_waves_path, false);
SWD swd_war = SWD.readSWD(filedata, 0); //Second arg is offset from file start to begin reading
filedata = FileBuffer.createBuffer(swd_art_path, false); //Open the articulation data file
SWD swd_art = SWD.readSWD(filedata, 0); //Parse as SWD
swd_art.loadSoundDataFrom(swd_war); //Load the sound data from the sound SWD to the articulation SWD
swd.writeSF2(sf2_path);
Probably with a try/catch to get those I/O and parsing exceptions.
And of course since this is all open source, feel free to look at SWD.java and be like "noooo, that's not good".
If yall are interested in using this as a converter, I wouldn't mind prioritizing debugging and cleaning up the SWD stuff. I can also just JAR up a dedicated SWD/SWD->SF2 command line tool.
For sure, SF2 lacks some flexibility that would be nice to have... I mostly only use it as the "default soundbank conversion target" because it's usually recognized by a lot of programs? Only thing I could get to import into my version of Kontakt.
(Attached most recent output of bgm0025.sf2)
bgm0025.sf2