New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Load MT-32 ROMs from romdir
using hash matches
#2591
Conversation
looks good, @weirddan455. Just a couple suggestions, and then if you can squash on your side to reduce the intermediate commits, then that should be it! Thanks again 🚀 |
Just did a force push with your new suggestions + squashing everything into one commit. Thanks for the fast review :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks OK to me.
Looks great, @weirddan455 ! It just hit me that having unit tests for this new insensitive directory search would be helpful, too. We use very basic tests; if you can look into the tests/ directory, checkout The debug builds always have unit tests: meson setup -Dbuildtype=debug build/debug
meson compile -C build/debug To launch just the ./build/debug/tests/fs_utils Or run all the tests: meson test -C build/debug |
@kcgen Sure I'll take a look at that in a bit. I'm thinking if we need something reproducible like a unit test, the function might need to sort the directory contents alphabetically and return the first result. Right now it's arbitrary what gets returned if the directory contains files with the same names but different casing. I see this function does something similar (except with the POSIX glob function): dosbox-staging/include/fs_utils.h Lines 53 to 70 in b8f72a0
|
I think it's OK to keep this new function std::filesystem 'clean', which I think it is, right now. The filesystem::path is very robust in terms of handling OS variations, and so combining a Perhaps for this function, we'll need to use filesystem's canonical handling, that can bake down nonsense like ./././testfile just to testfile. (Includeling these strange forms in the unit tests might reveal the need for the filename portion to be canonicalized too). Regarding alphabetic sorting; it sounds reasonable, but when I think it through, for example: MyFiLE ... Well, we're already in random land where case doesn't matter. So sorting is trying to apply casing rules into a space where casing has no meaning. User A might complain that it should have picked his lowercase file first, but user B might want her uppercase file instead. Both are invalid.. these users need to cleanup their ambiguous messes. Back to the mt32 use case, we do know that if users have files 'as-is' (with casing straight from the zip files), then we want to always search for those expected filenames first, and then fallback to case insensitive. So perhaps we can keep the direct-hit first (apologies if that's already in place but I just didn't notice😅) |
💯 fully agree.
To me the "gold standard" solution at the high level would be this:
This requires a little more "plumbing" and some persistent storage for sure, but it's a much more user-friendly and robust solution. WinUAE has this but with no auto-scanning: you chuck a bunch of random Kickstart ROM files you "acquired" into the ROM folder and press a button that rescans the whole folder and populates a drop-down with the names of the valid ROMs. Then the list of found ROMs is persisted across restarts in a config file, of course, until you decide to re-scan the ROM folder again. Easy, robust, and user-friendly! ScummVM has a similar functionality where you just point it to a folder that has all your games in subfolders, then ScummVM imports all the ones it can identify. |
Most of my good ideas for this project have been stolen from SheepShaver. Its good WinUAE is a similar conduit for you. 🙂 |
@johnnovak I really like that solution. I just modified the PR to do away with hard coded filenames. The mt32emu library we are using has a method I also removed the idea of "unversioned ROMs" and moved everything so it has a 1 to 1 link with what mt32emu is doing. Could still use caching in persistent storage, as you suggested. I put that a TODO comment in there for now. |
This is great @weirddan455! I'm glad you're tackling this; I like your enthusiasm! 🎉
💯 🥇
I think we need to leave that in for compatibility reasons. Other DOSBox forks use the "unversioned" ROMs if they are in a set location or in the local game folder (I think, but don't quote me on the exact lookup behaviour). So basically we only want to keep this for compatibility with existing gamepacks that have whatever MT-32 ROM versions bundled with the game. But yes, this is just for compatibility; when configuring a game from scratch, we discourage the use of non-versioned ROMs, absolutely.
Actually, thinking about this more deeply, it's hard to detect if the contents of a folder have changed in a cross-platform manner. So if we can get away with no caching, that's always the better and more robust solution. Could you perhaps measure (e.g. log the time taken) how long it takes to scan the full MT-32 ROM set at startup? I'm pretty sure the limiting factor here is disk I/O; even old hardware can calculate SHA1 hashes at faster rates than reading from disk. Ideally, if this only adds a few hundred milliseconds at most, then we most definitely don't need caching. |
For the scanning, the catch will be if a user has a couple SF2 files in there as well (which might be 500+ MB). On a desktop w/ SSD, their startup time might still be quick :-) But we could probably glob We could also log a warning for files it scans that have nothing to do w/ mt32emu (when mt32emu return a failure core). This would encourage the user to maintain a very clean |
Yeah, I was gonna say, people shouldn't put all sorts of crap into the I propose a slightly different coarse filtering: we know for certain the expected filesizes of the valid ROM files. So let's add a whitelist of valid filesizes and only calculate the SHA1 hash for those. The side-effect is that even if some random other files have the whitelisted filesizes (extremely unlikely), calculating the hash for them won't be a problem as the ROM files are all rather small. We could still log a warning for all the various random crap we find in the MT32 ROM folder, sure. But I'd still like to see some concrete timing measurements for calculating the hashes for the whole ROMset. |
I believe this should still work with my patch. "unversioned" ROMs were really just versioned ROMs with specific filenames which our code excluded from version checks. However, they still went through the exact same path with regards to mt32emu so I believe they will still work now (and further more now be recognized as the real version that they are). Of course, testing would be welcome to know for sure.
Sure. Is there a particular benchmarking or profiling tool you would recommend for this?
I had a look through the mt32emu source code as I was writing this and this is already done. Filesize gets matched before the SHA gets calculated: Filesize + SHA compare |
You can easily test this yourself by getting hold of some of the "unversioned" ROMs. I'm a bit busy, but I can send you those files later if you're on Discord.
No, just measure delta time in the code and log the results.
Nice, these guys have thought of everything! We only need to use these functions then! 🚀 |
So it's pretty fast on my system. I wrapped this dosbox-staging/src/midi/midi_mt32.cpp Line 562 in d178d1e
67ms - Debug build pre-patch 11ms - Release build pre-patch As far as the "unversioned" ROMs, I can confirm the following 2 sets are working (after the latest commit where I found one was missing). CM32L "unversioned" MT32 "unversioned" Lastly, the code is already calling the |
@sergm , nice to see @weirddan455 leveraging mt32emu's ROM loading features even more directly in this PR! This will open up access to all the models currently supported by mt32emu:
|
@kcgen Yes, that is the idea. I haven’t added all of those yet. I believe 2.06 and 2.07 are missing. Those probably need new config options as well since they were never supported by us. |
Contacted @sergm, who might be able to help in this regard. I will follow up via email. hmm - there's also an 'M9 enhanced' firmware referenced in the MAME MT-32 sources. for general ref, I believe this is where active MT-32/CM32 version and ROM status is being held: https://en.wikipedia.org/wiki/User:Lord_Nightmare |
Those are great results @weirddan455 regarding the timings. I suspect the detection of the full ROM-set won't take too long even on underpowered devices then such as the Raspberry Pi4. I have uploaded a while ago the full MT-32 ROM set to archieve.org along with instructions how to create the "unversioned" files out of them, if that helps with testing. I will add 2.06 and 2.07 to it once we get hold of them. https://archive.org/details/Roland-MT-32-ROMs We also need to update the output of the MIXER command for the new ROMs, but let's treat that separately: We can simply move the path to the current MT32 ROM below the little table that lists the found MT32 versions. That would be an improvement for other reasons too because then the ROM path could use the full width of the screen. |
romdir
using hash matches
Partially resolved, messaged in Discord. |
I pushed a commit yesterday for the items @johnnovak pointed out (added logging of unknown files and removed the TODO comment). I just added support for the rest of the ROMs supported by mt32emu. Thanks to @kcgen for providing the 2.07 ROM to test with. The mixer command now also lists the additional models. I believe @kcgen wrote the mt32 |
Tested it and it's working great! The PR is also a surprisingly small modification for such a big (and welcome) change in the loading functionality! Three comments:
Some users are going to point |
I don't want to bloat this PR too much but can you throw this in while you're at it. Also can be included in a follow-up PR that categorises the different ROM sets as indicated above. Mainly the green highlight colouring of the active munt ROM like it was before and is with fluidsynth. It also acts as a great way to ascertain are you on |
Good point @Grounded0 but let's treat that separately as restoring the highlighting is already half-implemented on a branch of mine. I'll finish it after this has been merged. |
Before you guys go into redesigning the But probably it's best to merge this as is, then the visual refactoring can be done in a separate ticket (I'm happy to do it). |
Cool. I just pushed commits fixing the duplicate logging and re-ordering the ROMs as @kcgen suggested. I tried setting the mixer output to show the full name but it failed an assertion and crashed because there was not enough room on the terminal to display so I didn't do any changes there. Agreed that the mixer output should probably be on a separate ticket. |
If @kcgen agrees, I think now that the order and the logging is fixed, this is good to go. Thanks for your help, much appreciated! ❤️ Then @kcgen and myself can brainstorm about the UI improvements and treat it separately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for working through several iterations, @weirddan455 ! Let's get this merged; it's a big improvement, and nicely scoped just to the loading.
Compilation issue on macOS: https://github.com/dosbox-staging/dosbox-staging/actions/runs/5284347668/jobs/9562708411 |
@weirddan455 - I think we're set to merge! One small suggestion, if you can reorder and combine (squash) a couple commits, I think there are three groups of changes: Also suggest naming the commits using the active voice like you've done in the first four and last commits (without the PS- apologies for the bloated image (on a 4k monitor..) |
Looks great, @weirddan455. All commits build and run clean. |
Thanks @weirddan455! 😎 |
Regression from PR #2591. The logic for these still works. It's a simple reverse string search. They were just accidently removed from the list of valid config values.
Hi, first PR to this project. I ran into an issue getting MT32 emulation working on my system and realized it was due to case sensitivity. The names of the ROMs are hardcoded here:
dosbox-staging/src/midi/midi_mt32.cpp
Lines 74 to 98 in b8f72a0
I figured it might be useful to search for these files in a case insensitive manner instead so that's what this patch does. It would have saved me, as a user, a bit of time diagnosing this problem in any case.