VOGONS


Reply 20 of 34, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I tried merging both patches. but I am a bit afraid of the following situation:
Game sets audio volume for cdrom (on the cdrom itself),
and resets the mixer => cd audio volume lost again.
Technically the cdrom could control the volume of the cable that goes from the cdrom to the card. So they should independent. So I was thinking of the following hack.
Use the chan->setscale call to implement the cdrom volume (simply selecting the highest volume reported for output 0 and 1 as scale factor.

Not sure if this a good idea though. It wouldn't add support for different channels being played, but it does allow basic volume control.

Water flows down the stream
How to ask questions the smart way!

Reply 21 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I was thinking of a special AddSample function, or pre-processing function, of the mixer that would process a sample buffer to apply scaling (volume) and duplicate/swap/silence (channel assignments). Then you'd just need to pass the settings from the MSCDEX driver to the function from the CD audio callback. Maybe the same could also be used with other mount types that use audio extraction. I'll keep fiddling with the code I got started on for it.

Reply 22 of 34, by gm_matthew

User metadata
Rank Newbie
Rank
Newbie

Ah yes, I developed that patch on SF.net after getting fed up of hearing both musics in Pinball Illusions at the same time. It is indeed a bit of a hack, but I didn't feel up to implementing a proper solution at the time. A proper solution would involve controlling the audio extracted from the CD or image and leaving the DOSBox mixer alone.

That similar patch for games that use the SB to control CD audio volume looks neat enough. Too bad that both of our patches directly control the DOSBox mixer and so we can't use both just yet without messy results.

I have a little idea about how to implement both patches, I'll have a look to see what I can do.

Reply 23 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

DOSBox connects the other SB mixer controls to its own mixer, so doing the same with the CD audio volume control is only natural, and makes me wonder "Why doesn't it do this already?" The CD mixer control is used by the CD version of Little Big Adventure when an SB16 is the configured sound card, and there might be other games that benefit from having it implemented.

A proper solution would involve controlling the audio extracted from the CD or image and leaving the DOSBox mixer alone.

Yes, I mentioned that in a couple of my comments in this thread, but also consider the channel mapping (see here) in addition to volume.

Reply 24 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

The attached patch implements CD audio channel control for image and ioctl_dx mount types. The channel-mapped audio in Chronicles of the Sword is correctly duplicated on both channels. The volume control also appears to be working in my tests, but I don't have a CD version of Pinball Illusions to try.

The mapping and volume data for all *four* channels is maintained, but nothing is done with the two "prime" channels; not sure what they're used for.

Any strange channel mapping is forced to defaults. Perhaps it causes a silent channel on real systems, but probably not important unless a game is found to need that.

The sample processing loop in cdrom_image.cpp might need big-endian handling. I think I understand how the host reading and writing works, but have no way to test it.

The setup program in Chronicles of the Sword has a problem where the first audio track played to determine the channel mapping is not heard. It initially starts playing audio with a length of zero, which causes a problem where the next bit of audio is paused instead of being played. The included fix might not be ideal, but it works for CotS.

Reply 25 of 34, by gm_matthew

User metadata
Rank Newbie
Rank
Newbie

I think your patch is probably as good a solution as is possible to this problem. However, I've encountered a weird bug:

The extracted audio samples are not scaled properly, e.g. setting the audio volume to 10% actually results in it being scaled to 1%. However, tiny parts of the extracted sample are the correct volume (10%), which all combined lead to horrible distortion.

It seems that most of the audio is being scaled twice, because with the audio volume at 50% it comes out at 25%. At full volume (with a slight modification to always force the scaler on), the audio is perfect.

I've had a look, but I haven't found the cause of the problem yet.

Reply 26 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

hmm, maybe dividing length by 4 in the sample processing loop?

for (Bitu pos=0;pos<len/4;pos++) {

Edit: I think I reproduced the distortion, and the above corrected it.

Reply 28 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Well, the calls to AddSample are dividing by 4. It seems the problem isn't noticeable with channel mapping or zero/full volume, only partial volume.

Reply 29 of 34, by gm_matthew

User metadata
Rank Newbie
Rank
Newbie

I changed the appropriate lines, and it now works perfectly. Funny how one tiny number can cause such an annoying problem.

EDIT: I've just discovered a bug where the audio plays at zero volume until the ChannelControl function is called, which would be a problem for any games that use CD audio but do not use audio channel control. I've found that this is because the CDROM interface audio channel data is uninitialized. I managed to fix this by changing this code at the end of AddDrive:

 	// init channel control
for (Bitu chan=0;chan<4;chan++) {
dinfo[subUnit].audioCtrl.out[chan]=chan;
dinfo[subUnit].audioCtrl.vol[chan]=0xff;

}

to this:

 	// init channel control
TCtrl ctrl;
for (Bitu chan=0;chan<4;chan++) {
ctrl.out[chan]=chan;
ctrl.vol[chan]=0xff;
}
ChannelControl(subUnit, ctrl);

EDIT 2: Don't worry about this fix, the bug was only in my version because I had changed something.

Last edited by gm_matthew on 2010-05-06, 15:35. Edited 1 time in total.

Reply 30 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

You've only managed to fix what you somehow managed to break, because the problem you describe shouldn't be possible. player.ctrlUsed is false, and therefore no processing occurs, until ChannelControl() is called on the drive unit, and at that point values from the dinfo struct have been passed in. The ctrlUsed boolean is also how processing can be shut down when a game reverts to normal mapping and full volume. Anyway, audio is definitely working if channel control is never used.

After testing some games with CD audio, it appears that channel control is used to change volume more often than the SB mixer. It makes sense, as games often support different types of soundcards. Grand Theft Auto, Shadow Warrior, Tomb Raider, and Warcraft 2 are some noteworthy titles that change volume through channel control.

For example, Tomb Raider sets the volume to zero when you enter its ring menu, and not hearing the atmospheric background sounds reminds you that the game is paused. The volume is also set to zero when Lara dives underwater. The car radio in GTA is reduced in volume when you drive under something like a bridge or overpass, so it appears that you're hearing it from your vantage point above. Small touches like these are obviously not vital to enjoying the games, but it is nice when they work as intended.

Reply 31 of 34, by gm_matthew

User metadata
Rank Newbie
Rank
Newbie

Ah, I've just discovered what was causing my version to not work. I had changed the line "if (player.ctrlUsed)" to "if (player.ctrlUsed || 1)" to test the effect when CD audio plays at full volume, back when we still had the "divide length by 2" issue. And I had simply forgotten to change it back. I've changed it back now.

Reply 32 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

A revised version of the channel control patch is attached that fixes the audio distortion problem, and has a tweak to shut down the extra processing when very close to full volume. I have observed a few games that use increments for the volume that are powers of 2, and 254 (0xfe) is used for full volume. A goal of the patch is to avoid doing more work if it isn't really needed, so the shutdown point is changed from 255 to 254.

Reply 33 of 34, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

think everything above 0xf0 can be considered full volume.
recall the mscdex specs say something like if the cdrom supports 16 volume levels make it so that
0-0xf => vol 1 0x10-0x1f vol 2 etc. The games I have seen only support something like 8 different volume levels

Water flows down the stream
How to ask questions the smart way!

Reply 34 of 34, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

GTA has 8 levels, with 254 for full volume. Dungeon Keeper has 0-127 positions on its slider, increments of 2, max of 254. Warcraft 2 is similar to DK, but has 255 for maximum. But this is what the game programs the channels with; what a drive's resolution is, and what you can audibly differentiate are different. I think having greater resolution available than what real drives provide is a useful enhancement, as long as there are games that support that much resolution, and it appears there are.