ValleyBell / SMPSPlay

A player for SMPS files, a format commonly used in Sega MegaDrive games.
37 stars 6 forks source link

No way to avoid clipping #2

Closed westonlast closed 7 years ago

westonlast commented 7 years ago

Please add a volume option to prevent clipping (like, at least half). Without it, this player is useless for enjoyment.

I see this: https://github.com/ValleyBell/SMPSPlay/commit/a108ed3ceae75b9b7e58a2e0e146ebc6ef0f3eb4

But a month too late! You don't expect me to build this, do you? :(

Oh yeah, that build I was talking about? Doesn't work. Requires https://github.com/ValleyBell/libvgm , and that build doesn't work either. Rabbit hole++!

Let's qualify this: "Doesn't work" as in if you don't want to screw around with Microsoft and Visual Studio/MSBuild/today's greatest Microsoft idea. (I did, and it still didn't work.)

Shouldn't requiring CMake suggest that an MSYS or MinGW build will work? They don't. <dsound.h>

I love building.

ValleyBell commented 7 years ago

The correct issue would be "unable to build" then, I guess.

Anyway, it looks like I indeed broke something. The current SMPSPlay makefile isn't compatible with the libvgm one and it throws linker errors about __stack_chk_fail. In order to fix this, you either need to add -fstack-protector to the LDFLAGS in SMPSPlay or remove it from CFLAGS/LDFLAGS (makefile) or CMAKE_C_FLAGS/CMAKE_EXE_LINKER_FLAGS (CMakeLists.txt) in libvgm.

Of libvgm, you (currently) only need the libaudio module. (libemu didn't exist back when I started SMPSPlay.) If you don't like CMake, you can also build that using make libaudio.
dsound.h should be present in MSYS2 environments. I don't remember installing it. If you can't get around that error, just disable AUDIODRV_DSOUND in CMake.
After compiling, you need to copy libaudio.a into SMPSPlay/libs/lib/. You also need to copy header files as described in RequiredLibs.txt. (Yeah, sorry, I didn't know about git submodules back then.)

From within MSYS2, you can run SMPSPlay with start ./smpsplay. (running inside the MSYS console doesn't seem to work due to the way the interface works)

westonlast commented 7 years ago

Well, the real issue is that SMPSPlay has never had a way to reduce its output amplitude, even after release in 2014. The lack of a recent build is incidental. Please release another official build ("2.12" or something), because clipping kills the whole purpose of this (if you care about quality audio).

By the way, the 32-bit floating point sample format also clips to 1.0. Kind of pointless, no?

It might be easier for me to try to hack in a lesser amplitude scale factor than to build this program. Great modern times, eh? Builds never work!

ValleyBell commented 7 years ago

The next release is coming when preSMPS support is finished. (which is at about 90% right now - I just happened to get stuck/lose motivation right before finishing it)

If you can't get the current version to build, you can always try building the one with the v2.11 tag. (It's the last commit before I switched to the libvgm audio system.) Volume control is done with a bit-shift-right >> in Sound.c.

The WIP version doesn't support 32 bit float, btw. Supported sample formats are 8, 16, 24 and 32 bit integer.

westonlast commented 7 years ago

I thought you should benefit from the fruits of your labors:

https://hcs64.com/mboard/forum.php?showthread=50454

ValleyBell commented 7 years ago

Oh, neat, thanks.
I just remembered something, btw: You could've just dumped all of the songs to VGM and convert those to WAV. That's what I usually do, as it gives you full control over volume and sample rates. And it does automatic fade outs. And you don't need to extract single songs from a huge WAV dump.

tl;dr: Turn VGM logging + automatic progressing on, start the first song, mute SMPSPlay via Windows' volume control and let it run for an hour. (and look at it every now and then, loop detection doesn't always work) Then convert the VGMs to WAV/MP3 using your favourite VGM player.
-> minimum effort SMPS to WAV
The only drawback is that it doesn't work with 2-channel DAC stuff. (and the old version doesn't support DAC volume control) But those cases are pretty rare.

westonlast commented 7 years ago

Thanks for the tips. So the high-quality SMPS DAC playback is compatible with the hardware YM2612 (because VGM logging results in equivalent output)? I thought that maybe the DAC samples were magically played back with uber, Personal-Computing powers and then simply mixed back into the non-DAC channels of the YM2612. I was wondering, then, what sort of interpolation happens when "none" is selected. In any case, "none" sounded better than "linear" with these low-sample-rate samples.

Yeah, it took a long time. I tried automatic progression, but Flying Battery played forever (and instruments started getting out of sync and doing weird things)... I just didn't want to deal with that. Must be something wrong with that particular song rip?... But then you said there's loop "detection," which could be at the instruction or even output sample level? I couldn't hear a difference with the single loop and manual fadeout point on any tracks, so yay.

"2-channel DAC stuff" - As in stereo or dual DAC? I guess "dual DAC" is implied. Dusting off my YM2612 knowledge.

ValleyBell commented 7 years ago

If you set PCM resampling to "none", that's how most DAC drivers sound on the MegaDrive. The only real improvement is that the PCM sample stream isn't stopped whenever there is sound processing. (The latter is done in zero "emulation time" due to PC powers.) A very well optimized sound driver may achieve the same quality.

If your Flying Battery song didn't loop and desync'ed, you probably used the buggy Sonic 3 version. They fixed that song (and a few others) in S&K. Loop detection is done at the level of SMPS song data. (SMPS is a bit similar to ASM code and allows arbitrary jumps within the song. A loop is detected when a byte that was previously played is played again.)

The YM2612 DAC is mono. (You can just mute the left or right speaker.) "2-channel DAC" means mixing 2 virtual PCM channels in software and outputting it to 1 YM2612 DAC channel. (e.g. Ristar does this)

You should join the #vgmrips IRC channel if you want to discuss this in depth, btw. We're really going off-topic here.

ValleyBell commented 7 years ago

I'll close this issue, because what you wanted was sort of solved. And the actual issue was invalid anyway. (You requested a feature that's already there.)