Opened 5 months ago

Closed 2 months ago

#15208 closed defect (fixed)

SCI: KQ4: Death Music is Almost Inaudible

Reported by: ArthurWalden Owned by: athrxx
Priority: normal Component: Engine: SCI
Version: Keywords: kq4, sci, death volume
Cc: ArthurWalden Game: King's Quest 4

Description

I am using ScummVM version 2.9.0git4942-g420e53e9c8d (daily build).

In King's Quest 4 (SCI version), there seems to be some music that plays when you die (i.e. when the "Roberta Williams says:..." death box appears), but I it is so soft I cannot really hear it. To be clear, the rest of the sound plays normal volume, so the problem is not the volume setting on my system.

I am playing the English GOG version of the game.

I am running the game on Windows 11 Home, version 23H2.

Change History (8)

comment:1 by antoniou79, 5 months ago

What are your audio settings for the game (or the global ones if you are not overriding them)?

comment:2 by ArthurWalden, 5 months ago

Whoops...it seems I left the music device on default, rather changing it to my VirtualMIDISynth. The music sounds much better now overall.

comment:3 by antoniou79, 5 months ago

I have noticed that, when the "IBM PCjr emulator" is set for music device, it does sound significantly low, and I am unsure if the volume settings (ScummVM launcher, or GMM, or native in-game menu) affect it at all.

This was tested on ScummVM 2.8.1 and on a recent dev build of ScummVM 2.9.0git.

In comparison, on King's Quest 3 (AGI, GOG version) the music is not low with that device setting and additionally the volume is clearly affected by the (ScummVM GMM) music volume controls.

in reply to:  3 comment:4 by eriktorbjorn, 3 months ago

Replying to antoniou79:

I have noticed that, when the "IBM PCjr emulator" is set for music device, it does sound significantly low, and I am unsure if the volume settings (ScummVM launcher, or GMM, or native in-game menu) affect it at all.

When I tried it, the music volume was apparently set to 11 by calling MidiPlayer_PCJr::setVolume(). The call came by way of MidiParser_SCI::setMasterVolume(). Given that engines/sci/sound/music.h defines MUSIC_MASTERVOLUME_MAX as 15, this is presumably a decently high volume.

But there's also MUSIC_VOLUME_MAX that is defined as 127, so by that scale 11 is a very low volume.

The default _global_volume for the PCjr driver is 100, so I assume we're using the wrong scale for the setVolume() call here.

comment:5 by eriktorbjorn, 3 months ago

So what does setVolume() in the various drivers seem to expect?

Driver Comment
adlib.cpp The default volume is 15
amigamac0.cpp The volume is clipped to 0-15. The default is 15.
amigamac1.cpp The default volume is 15
casio.cpp I'm not sure
cms.cpp I'm not sure
fb01.cpp The volume is clipped to 0-15. The default is 15.
fmtowns.cpp I'm not sure
midi.cpp The default volume is 15
pc9801.cpp The volume has to be < 16, though internally a different scale is used.
pcjr.cpp The default volume is 100

So PCjr may be the odd one out here.

comment:6 by eriktorbjorn, 3 months ago

Just to clarify, I think the solution is to simply change the SCI engine's MidiPlayer_PCJr::setVolume() method, so that it converts the volume to whatever MidiDrive_PCJr expects. This is what it currently looks like:

	void setVolume(byte volume) override { static_cast<MidiDriver_PCJr *>(_driver)->_global_volume = volume; }

It's just the exact conversion that I'm uncertain about.

comment:7 by eriktorbjorn, 3 months ago

Here's a possible fix the volume. It assumes that a) volumes are in the 0-127 range, and b) the bit about the volume table in https://www.smspower.org/Development/SN76489 is applicable here.

I haven't seen any PCjr channel volume in the Sierra games I fired up be greater than 127. The global volume and the channel volume have the same default, so I've assumed they used the same range.

diff --git a/engines/sci/sound/drivers/pcjr.cpp b/engines/sci/sound/drivers/pcjr.cpp
index c1fd4c1de56..53c2d39e8c2 100644
--- a/engines/sci/sound/drivers/pcjr.cpp
+++ b/engines/sci/sound/drivers/pcjr.cpp
@@ -235,7 +235,15 @@ public:
        byte getPlayId() const override;
        int getPolyphony() const override { return 3; }
        bool hasRhythmChannel() const override { return false; }
-       void setVolume(byte volume) override { static_cast<MidiDriver_PCJr *>(_driver)->_global_volume = volume; }
+
+       void setVolume(byte volume) override {
+               byte volTable[16] = {
+                       0, 5, 6, 8, 10, 12, 15, 20,
+                       25, 31, 40, 50, 64, 80, 100, 127
+               };
+
+               static_cast<MidiDriver_PCJr *>(_driver)->_global_volume = volTable[CLIP<byte>(volume, 0, 15)];
+       }
 };
 
 byte MidiPlayer_PCJr::getPlayId() const {

comment:8 by bluegr, 2 months ago

Owner: set to athrxx
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.